mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-22 10:00:33 +00:00
On Linux show in crash message box the backtrace
This commit is contained in:
parent
bcbc162665
commit
2f17858115
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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; }
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user