Discussion:
[PATCH 1/1] On Linux show in crash message box the backtrace
s***@gmx.net
2014-06-07 09:48:47 UTC
Permalink
From: Peter Kümmel <***@lyx.org>


Signed-off-by: Peter Kümmel <***@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
Peter Kümmel
2014-06-07 09:55:04 UTC
Permalink
Post by s***@gmx.net
--- 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()
+
Automake build needs to be patched.

Peter
Peter Kümmel
2014-06-07 09:56:59 UTC
Permalink
This patch is for 2.1.x, but could I commit to master?
Post by s***@gmx.net
---
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
// 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);
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
/// 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
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
Richard Heck
2014-06-07 16:37:28 UTC
Permalink
Post by Peter Kümmel
This patch is for 2.1.x, but could I commit to master?
I'd think it would be fine for master.

Richard
Post by Peter Kümmel
Post by s***@gmx.net
---
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
// 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);
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
/// 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
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]);
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])
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
Loading...