On Linux show in crash message box the backtrace

This commit is contained in:
Peter Kümmel 2014-06-07 11:12:31 +02:00 committed by Peter Kümmel
parent bcbc162665
commit 2f17858115
10 changed files with 49 additions and 32 deletions

View File

@ -667,7 +667,7 @@ static void error_handler(int err_sig)
if (!msg.empty()) { if (!msg.empty()) {
lyxerr << "\nlyx: " << msg << endl; lyxerr << "\nlyx: " << msg << endl;
// try to make a GUI message // try to make a GUI message
Alert::error(_("LyX crashed!"), msg); Alert::error(_("LyX crashed!"), msg, true);
} }
// Deinstall the signal handlers // Deinstall the signal handlers

View File

@ -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. * Display a warning to the user. Title should be a short (general) summary.
* Only use this if the user cannot perform some remedial action. * 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 * Informational message. Use very very sparingly. That is, you must

View File

@ -24,6 +24,7 @@
#include "support/debug.h" #include "support/debug.h"
#include "support/docstring.h" #include "support/docstring.h"
#include "support/lstrings.h" #include "support/lstrings.h"
#include "support/lassert.h"
#include "support/ProgressInterface.h" #include "support/ProgressInterface.h"
#include <QApplication> #include <QApplication>
@ -197,12 +198,17 @@ void warning(docstring const & title0, docstring const & message,
title0, message, askshowagain); 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' lyxerr << "Error: " << title0 << '\n'
<< "----------------------------------------\n" << "----------------------------------------\n"
<< message << endl; << message << endl;
QString details;
if (backtrace) {
details = QString::fromLocal8Bit(to_local8bit(printCallStack()).c_str());
}
if (!use_gui) if (!use_gui)
return; return;
@ -223,7 +229,8 @@ void doError(docstring const & title0, docstring const & message)
ProgressInterface::instance()->error( ProgressInterface::instance()->error(
toqstr(title), toqstr(title),
toqstr(message)); toqstr(message),
details);
qApp->restoreOverrideCursor(); qApp->restoreOverrideCursor();
@ -231,14 +238,14 @@ void doError(docstring const & title0, docstring const & message)
theApp()->startLongOperation(); theApp()->startLongOperation();
} }
void error(docstring const & title0, docstring const & message) void error(docstring const & title0, docstring const & message, bool backtrace)
{ {
#ifdef EXPORT_in_THREAD #ifdef EXPORT_in_THREAD
InGuiThread<void>().call(&doError, InGuiThread<void>().call(&doError,
#else #else
doError( doError(
#endif #endif
title0, message); title0, message, backtrace);
} }
void doInformation(docstring const & title0, docstring const & message) void doInformation(docstring const & title0, docstring const & message)

View File

@ -56,8 +56,8 @@ GuiProgress::GuiProgress()
SLOT(doWarning(QString const &, QString const &))); SLOT(doWarning(QString const &, QString const &)));
connect(this, SIGNAL(toggleWarning(QString const &, QString const &, QString const &)), connect(this, SIGNAL(toggleWarning(QString const &, QString const &, QString const &)),
SLOT(doToggleWarning(QString const &, QString const &, QString const &))); SLOT(doToggleWarning(QString const &, QString const &, QString const &)));
connect(this, SIGNAL(error(QString const &, QString const &)), connect(this, SIGNAL(error(QString const &, QString const &, QString const &)),
SLOT(doError(QString const &, QString const &))); SLOT(doError(QString const &, QString const &, QString const &)));
connect(this, SIGNAL(information(QString const &, QString const &)), connect(this, SIGNAL(information(QString const &, QString const &)),
SLOT(doInformation(QString const &, QString const &))); SLOT(doInformation(QString const &, QString const &)));
connect(this, SIGNAL(triggerFlush()), 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();
} }

View File

@ -62,7 +62,7 @@ Q_SIGNALS:
// Alert interface // Alert interface
void warning(QString const & title, QString const & message); void warning(QString const & title, QString const & message);
void toggleWarning(QString const & title, QString const & msg, QString const & formatted); 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 information(QString const & title, QString const & message);
private Q_SLOTS: private Q_SLOTS:
@ -74,7 +74,7 @@ private Q_SLOTS:
void doWarning(QString const &, QString const &); void doWarning(QString const &, QString const &);
void doToggleWarning(QString const & title, QString const & msg, QString const & formatted); 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 doInformation(QString const &, QString const &);
void updateWithLyXErr(); void updateWithLyXErr();

View File

@ -41,6 +41,10 @@ else()
set(support_linkback_headers "") set(support_linkback_headers "")
endif() endif()
if(UNIX AND CMAKE_COMPILER_IS_GNUCC AND NOT APPLE)
add_definitions(-DLYX_CALLSTACK_PRINTING)
endif()
add_subdirectory(tests) add_subdirectory(tests)
# needed to compile tex2lyx in merged mode # needed to compile tex2lyx in merged mode

View File

@ -36,7 +36,7 @@ public:
/// Alert interface /// Alert interface
virtual void warning(QString const & title, QString const & message) = 0; 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 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 void information(QString const & title, QString const & message) = 0;
virtual int prompt(docstring const & title, docstring const & question, virtual int prompt(docstring const & title, docstring const & question,
int default_button, int cancel_button, int default_button, int cancel_button,

View File

@ -71,7 +71,7 @@ public:
void warning(QString const &, QString const &) {} void warning(QString const &, QString const &) {}
void toggleWarning(QString const &, 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 &) {} void information(QString const &, QString const &) {}
int prompt(docstring const &, docstring const &, int default_but, int, int prompt(docstring const &, docstring const &, int default_but, int,
docstring const &, docstring const &) { return default_but; } docstring const &, docstring const &) { return default_but; }

View File

@ -20,9 +20,8 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <QString>
//#define LYX_CALLSTACK_PRINTING
// must be linked with -rdynamic
#ifdef LYX_CALLSTACK_PRINTING #ifdef LYX_CALLSTACK_PRINTING
#include <cstdio> #include <cstdio>
#include <cstdlib> #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. docstring printCallStack()
void printCallStack()
{ {
#ifdef LYX_CALLSTACK_PRINTING #ifndef LYX_CALLSTACK_PRINTING
const int depth = 50; return docstring();
#else
const int depth = 200;
// get void*'s for all entries on the stack // get void*'s for all entries on the stack
void* array[depth]; void* array[depth];
@ -99,9 +99,9 @@ void printCallStack()
char** messages = backtrace_symbols(array, size); char** messages = backtrace_symbols(array, size);
for (size_t i = 0; i < size && messages != NULL; i++) { docstring bt;
std::string orig(messages[i]); for (size_t i = 1; i < size && messages != NULL; i++) {
// extract mangled: bin/lyx2.0(_ZN3lyx7support7packageEv+0x32) [0x8a2e02b] const std::string orig(messages[i]);
char* mangled = 0; char* mangled = 0;
for (char *p = messages[i]; *p; ++p) { for (char *p = messages[i]; *p; ++p) {
if (*p == '(') { if (*p == '(') {
@ -112,15 +112,16 @@ void printCallStack()
break; break;
} }
} }
int err = 0; int status = 0;
char* demangled = abi::__cxa_demangle(mangled, 0, 0, &err); const char* demangled = abi::__cxa_demangle(mangled, 0, 0, &status);
if (err == 0) { const QByteArray line = QString("(%1) %2: %3\n").arg(i, 3).arg(messages[i])
fprintf(stderr, "[bt]: (%d) %s %s\n", i, messages[i], demangled); .arg(demangled ? demangled : orig.c_str()).toLocal8Bit();
free((void*)demangled); free((void*)demangled);
} else {
fprintf(stderr, "[bt]: (%d) %s\n", i, orig.c_str()); fprintf(stderr, "%s", line.constData());
} bt += from_local8bit(line.constData());
} }
return bt;
#endif #endif
} }

View File

@ -66,7 +66,7 @@ void doBufErr(char const * expr, char const * file, long line);
void doAppErr(char const * expr, char const * file, long line); void doAppErr(char const * expr, char const * file, long line);
/// Print demangled callstack to stderr /// Print demangled callstack to stderr
void printCallStack(); docstring printCallStack();
} // namespace lyx } // namespace lyx