From: Peter Kümmel <kuem...@lyx.org>

Signed-off-by: Peter Kümmel <kuem...@lyx.org>
---
 src/LyX.cpp                       |    2 +-
 src/frontends/alert.h             |    3 ++-
 src/frontends/qt4/GuiAlert.cpp    |   15 +++++++++++----
 src/frontends/qt4/GuiProgress.cpp |   12 ++++++++----
 src/frontends/qt4/GuiProgress.h   |    4 ++--
 src/support/CMakeLists.txt        |    4 ++++
 src/support/ProgressInterface.h   |    2 +-
 src/support/Systemcall.cpp        |    2 +-
 src/support/lassert.cpp           |   35 ++++++++++++++++++-----------------
 src/support/lassert.h             |    2 +-
 10 files changed, 49 insertions(+), 32 deletions(-)

diff --git a/src/LyX.cpp b/src/LyX.cpp
index b784831..98c5705 100644
--- a/src/LyX.cpp
+++ b/src/LyX.cpp
@@ -667,7 +667,7 @@ static void error_handler(int err_sig)
        if (!msg.empty()) {
                lyxerr << "\nlyx: " << msg << endl;
                // try to make a GUI message
-               Alert::error(_("LyX crashed!"), msg);
+               Alert::error(_("LyX crashed!"), msg, true);
        }
 
        // Deinstall the signal handlers
diff --git a/src/frontends/alert.h b/src/frontends/alert.h
index 4f05234..b96ca1e 100644
--- a/src/frontends/alert.h
+++ b/src/frontends/alert.h
@@ -48,8 +48,9 @@ void warning(docstring const & title, docstring const & 
message,
 /**
  * Display a warning to the user. Title should be a short (general) summary.
  * Only use this if the user cannot perform some remedial action.
+ * On some systems it is possible to show a backtrace.
  */
-void error(docstring const & title, docstring const & message);
+void error(docstring const & title, docstring const & message, bool backtrace 
= false);
 
 /**
  * Informational message. Use very very sparingly. That is, you must
diff --git a/src/frontends/qt4/GuiAlert.cpp b/src/frontends/qt4/GuiAlert.cpp
index 4e9a8e4..14cce93 100644
--- a/src/frontends/qt4/GuiAlert.cpp
+++ b/src/frontends/qt4/GuiAlert.cpp
@@ -24,6 +24,7 @@
 #include "support/debug.h"
 #include "support/docstring.h"
 #include "support/lstrings.h"
+#include "support/lassert.h"
 #include "support/ProgressInterface.h"
 
 #include <QApplication>
@@ -197,12 +198,17 @@ void warning(docstring const & title0, docstring const & 
message,
                                title0, message, askshowagain);
 }
 
-void doError(docstring const & title0, docstring const & message)
+void doError(docstring const & title0, docstring const & message, bool 
backtrace)
 {
        lyxerr << "Error: " << title0 << '\n'
               << "----------------------------------------\n"
               << message << endl;
 
+       QString details;
+       if (backtrace) {
+               details = 
QString::fromLocal8Bit(to_local8bit(printCallStack()).c_str());
+       }
+
        if (!use_gui)
                return;
 
@@ -223,7 +229,8 @@ void doError(docstring const & title0, docstring const & 
message)
 
        ProgressInterface::instance()->error(
                toqstr(title),
-               toqstr(message));
+               toqstr(message),
+               details);
 
        qApp->restoreOverrideCursor();
 
@@ -231,14 +238,14 @@ void doError(docstring const & title0, docstring const & 
message)
                theApp()->startLongOperation();
 }
 
-void error(docstring const & title0, docstring const & message)
+void error(docstring const & title0, docstring const & message, bool backtrace)
 {
 #ifdef EXPORT_in_THREAD
        InGuiThread<void>().call(&doError, 
 #else
        doError(
 #endif
-                               title0, message);
+                               title0, message, backtrace);
 }
 
 void doInformation(docstring const & title0, docstring const & message)
diff --git a/src/frontends/qt4/GuiProgress.cpp 
b/src/frontends/qt4/GuiProgress.cpp
index ab8c6bd..a44438d 100644
--- a/src/frontends/qt4/GuiProgress.cpp
+++ b/src/frontends/qt4/GuiProgress.cpp
@@ -56,8 +56,8 @@ GuiProgress::GuiProgress()
                SLOT(doWarning(QString const &, QString const &)));
        connect(this, SIGNAL(toggleWarning(QString const &, QString const &, 
QString const &)),
                SLOT(doToggleWarning(QString const &, QString const &, QString 
const &)));
-       connect(this, SIGNAL(error(QString const &, QString const &)),
-               SLOT(doError(QString const &, QString const &)));
+       connect(this, SIGNAL(error(QString const &, QString const &, QString 
const &)),
+               SLOT(doError(QString const &, QString const &, QString const 
&)));
        connect(this, SIGNAL(information(QString const &, QString const &)),
                SLOT(doInformation(QString const &, QString const &)));
        connect(this, SIGNAL(triggerFlush()),
@@ -183,9 +183,13 @@ void GuiProgress::doToggleWarning(QString const & title, 
QString const & msg, QS
 }
 
 
-void GuiProgress::doError(QString const & title, QString const & message)
+void GuiProgress::doError(QString const & title, QString const & message, 
QString const & details)
 {
-       QMessageBox::critical(qApp->focusWidget(), title, message);
+       QMessageBox box(QMessageBox::Critical, title, message, QMessageBox::Ok, 
qApp->focusWidget());
+       if (!details.isEmpty()) {
+               box.setDetailedText(details);
+       }
+       box.exec();
 }
 
 
diff --git a/src/frontends/qt4/GuiProgress.h b/src/frontends/qt4/GuiProgress.h
index 9bb8b23..80ab47a 100644
--- a/src/frontends/qt4/GuiProgress.h
+++ b/src/frontends/qt4/GuiProgress.h
@@ -62,7 +62,7 @@ Q_SIGNALS:
        // Alert interface
        void warning(QString const & title, QString const & message);
        void toggleWarning(QString const & title, QString const & msg, QString 
const & formatted);
-       void error(QString const & title, QString const & message);
+       void error(QString const & title, QString const & message, QString 
const & details = QString());
        void information(QString const & title, QString const & message);
 
 private Q_SLOTS:
@@ -74,7 +74,7 @@ private Q_SLOTS:
 
        void doWarning(QString const &, QString const &);
        void doToggleWarning(QString const & title, QString const & msg, 
QString const & formatted);
-       void doError(QString const &, QString const &);
+       void doError(QString const &, QString const &, QString const &);
        void doInformation(QString const &, QString const &);
 
        void updateWithLyXErr();
diff --git a/src/support/CMakeLists.txt b/src/support/CMakeLists.txt
index ba0dfdc..efb297c 100644
--- a/src/support/CMakeLists.txt
+++ b/src/support/CMakeLists.txt
@@ -36,6 +36,10 @@ else()
        set(support_linkback_headers "")
 endif()
 
+if(UNIX AND CMAKE_COMPILER_IS_GNUCC AND NOT APPLE)
+       add_definitions(-DLYX_CALLSTACK_PRINTING)
+endif()
+
 add_subdirectory(tests)
 
 # needed to compile tex2lyx in merged mode
diff --git a/src/support/ProgressInterface.h b/src/support/ProgressInterface.h
index 1efb79a..4a9a1ed 100644
--- a/src/support/ProgressInterface.h
+++ b/src/support/ProgressInterface.h
@@ -36,7 +36,7 @@ public:
        /// Alert interface
        virtual void warning(QString const & title, QString const & message) = 
0;
        virtual void toggleWarning(QString const & title, QString const & msg, 
QString const & formatted) = 0;
-       virtual void error(QString const & title, QString const & message) = 0;
+       virtual void error(QString const & title, QString const & message, 
QString const & details) = 0;
        virtual void information(QString const & title, QString const & 
message) = 0;
        virtual int prompt(docstring const & title, docstring const & question,
                           int default_button, int cancel_button,
diff --git a/src/support/Systemcall.cpp b/src/support/Systemcall.cpp
index de5de61..34d645e 100644
--- a/src/support/Systemcall.cpp
+++ b/src/support/Systemcall.cpp
@@ -71,7 +71,7 @@ public:
 
        void warning(QString const &, QString const &) {}
        void toggleWarning(QString const &, QString const &, QString const &) {}
-       void error(QString const &, QString const &) {}
+       void error(QString const &, QString const &, QString const &) {}
        void information(QString const &, QString const &) {}
        int prompt(docstring const &, docstring const &, int default_but, int,
                   docstring const &, docstring const &) { return default_but; }
diff --git a/src/support/lassert.cpp b/src/support/lassert.cpp
index 02e64bf..281330e 100644
--- a/src/support/lassert.cpp
+++ b/src/support/lassert.cpp
@@ -20,9 +20,8 @@
 
 #include <boost/assert.hpp>
 
+#include <QString>
 
-//#define LYX_CALLSTACK_PRINTING
-// must be linked with -rdynamic
 #ifdef LYX_CALLSTACK_PRINTING
 #include <cstdio>
 #include <cstdlib>
@@ -87,11 +86,12 @@ void doAppErr(char const * expr, char const * file, long 
line)
 }
 
 
-//TODO Return as string, so call stack could be used in dialogs.
-void printCallStack()
+docstring printCallStack()
 {
-#ifdef LYX_CALLSTACK_PRINTING
-       const int depth = 50;
+#ifndef LYX_CALLSTACK_PRINTING
+       return docstring();
+#else
+       const int depth = 200;
        
        // get void*'s for all entries on the stack
        void* array[depth];
@@ -99,9 +99,9 @@ void printCallStack()
        
        char** messages = backtrace_symbols(array, size);
        
-       for (size_t i = 0; i < size && messages != NULL; i++) {
-               std::string orig(messages[i]);
-               // extract mangled: bin/lyx2.0(_ZN3lyx7support7packageEv+0x32) 
[0x8a2e02b]
+       docstring bt;
+       for (size_t i = 1; i < size && messages != NULL; i++) {
+               const std::string orig(messages[i]);
                char* mangled = 0;
                for (char *p = messages[i]; *p; ++p) {
                        if (*p == '(') {
@@ -112,15 +112,16 @@ void printCallStack()
                                break;
                        }
                }
-               int err = 0;
-               char* demangled = abi::__cxa_demangle(mangled, 0, 0, &err);
-               if (err == 0) {
-                       fprintf(stderr, "[bt]: (%d) %s %s\n", i, messages[i], 
demangled);
-                       free((void*)demangled);
-               } else {
-                       fprintf(stderr, "[bt]: (%d) %s\n", i, orig.c_str());
-               }               
+               int status = 0;
+               const char* demangled = abi::__cxa_demangle(mangled, 0, 0, 
&status);
+               const QByteArray line = QString("(%1) %2: %3\n").arg(i, 
3).arg(messages[i])
+                                                               .arg(demangled 
? demangled : orig.c_str()).toLocal8Bit();
+               free((void*)demangled);
+
+               fprintf(stderr, "%s", line.constData());
+               bt += from_local8bit(line.constData());
        }
+               return bt;
 #endif
 }
 
diff --git a/src/support/lassert.h b/src/support/lassert.h
index 5a47edf..2aa30cf 100644
--- a/src/support/lassert.h
+++ b/src/support/lassert.h
@@ -66,7 +66,7 @@ void doBufErr(char const * expr, char const * file, long 
line);
 void doAppErr(char const * expr, char const * file, long line);
 
 /// Print demangled callstack to stderr
-void printCallStack();
+docstring printCallStack();
 
 
 } // namespace lyx
-- 
1.7.10.4

Reply via email to