From 4a91102306cd8ed75df4c5e771a716f006e76155 Mon Sep 17 00:00:00 2001 From: Nikolai Kosjar Date: Mon, 22 Oct 2012 13:45:10 +0200 Subject: [PATCH] CrashHandler: Display signal causing the crash. Change-Id: Ib6bb04b8e70bbe99e6517536a62c80a920a2ea01 Reviewed-by: hjk --- .../qtcreatorcrashhandler/crashhandler.cpp | 8 ++++---- src/tools/qtcreatorcrashhandler/crashhandler.h | 2 +- .../crashhandlerdialog.cpp | 17 ++++++++++------- .../qtcreatorcrashhandler/crashhandlerdialog.h | 6 ++++-- .../qtcreatorcrashhandler/crashhandlersetup.cpp | 10 ++++++---- src/tools/qtcreatorcrashhandler/main.cpp | 8 +++++--- 6 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/tools/qtcreatorcrashhandler/crashhandler.cpp b/src/tools/qtcreatorcrashhandler/crashhandler.cpp index c1046ed79c6..7521802716d 100644 --- a/src/tools/qtcreatorcrashhandler/crashhandler.cpp +++ b/src/tools/qtcreatorcrashhandler/crashhandler.cpp @@ -88,10 +88,10 @@ public: class CrashHandlerPrivate { public: - CrashHandlerPrivate(pid_t pid, CrashHandler *crashHandler) + CrashHandlerPrivate(pid_t pid, const QString &signalName, CrashHandler *crashHandler) : pid(pid), creatorInPath(Utils::Environment::systemEnvironment().searchInPath(QtCreatorExecutable)), - dialog(crashHandler) {} + dialog(crashHandler, signalName) {} const pid_t pid; const QString creatorInPath; // Backup debugger. @@ -103,8 +103,8 @@ public: QStringList restartAppEnvironment; }; -CrashHandler::CrashHandler(pid_t pid, QObject *parent) - : QObject(parent), d(new CrashHandlerPrivate(pid, this)) +CrashHandler::CrashHandler(pid_t pid, const QString &signalName, QObject *parent) + : QObject(parent), d(new CrashHandlerPrivate(pid, signalName, this)) { connect(&d->backtraceCollector, SIGNAL(error(QString)), SLOT(onError(QString))); connect(&d->backtraceCollector, SIGNAL(backtraceChunk(QString)), SLOT(onBacktraceChunk(QString))); diff --git a/src/tools/qtcreatorcrashhandler/crashhandler.h b/src/tools/qtcreatorcrashhandler/crashhandler.h index f0132b2025d..bf4c1991daa 100644 --- a/src/tools/qtcreatorcrashhandler/crashhandler.h +++ b/src/tools/qtcreatorcrashhandler/crashhandler.h @@ -43,7 +43,7 @@ class CrashHandler : public QObject { Q_OBJECT public: - explicit CrashHandler(pid_t pid, QObject *parent = 0); + explicit CrashHandler(pid_t pid, const QString &signalName, QObject *parent = 0); ~CrashHandler(); void run(); diff --git a/src/tools/qtcreatorcrashhandler/crashhandlerdialog.cpp b/src/tools/qtcreatorcrashhandler/crashhandlerdialog.cpp index 955ba6c2fb4..5d232557534 100644 --- a/src/tools/qtcreatorcrashhandler/crashhandlerdialog.cpp +++ b/src/tools/qtcreatorcrashhandler/crashhandlerdialog.cpp @@ -43,7 +43,8 @@ static const char SettingsApplication[] = "QtCreator"; static const char SettingsKeySkipWarningAbortingBacktrace[] = "CrashHandler/SkipWarningAbortingBacktrace"; -CrashHandlerDialog::CrashHandlerDialog(CrashHandler *handler, QWidget *parent) : +CrashHandlerDialog::CrashHandlerDialog(CrashHandler *handler, const QString &signalName, + QWidget *parent) : QDialog(parent), m_crashHandler(handler), m_ui(new Ui::CrashHandlerDialog) @@ -67,7 +68,7 @@ CrashHandlerDialog::CrashHandlerDialog(CrashHandler *handler, QWidget *parent) : connect(m_ui->debugAppButton, SIGNAL(clicked()), m_crashHandler, SLOT(debugApplication())); connect(m_ui->closeButton, SIGNAL(clicked()), this, SLOT(close())); - setApplicationInfo(); + setApplicationInfo(signalName); } CrashHandlerDialog::~CrashHandlerDialog() @@ -120,14 +121,16 @@ void CrashHandlerDialog::disableDebugAppButton() m_ui->debugAppButton->setDisabled(true); } -void CrashHandlerDialog::setApplicationInfo() +void CrashHandlerDialog::setApplicationInfo(const QString &signalName) { const QString ideName = QLatin1String("Qt Creator"); - const QString contents = tr( - "

%1 has closed unexpectedly.

" + const QString title = tr("%1 has closed unexpectedly (Signal \"%2\")").arg(ideName, signalName); + const QString introLabelContents = tr( + "

%1.

" "

Please file a bug report with the debug information provided below.

") - .arg(ideName, QLatin1String(URL_BUGTRACKER)); - m_ui->introLabel->setText(contents); + .arg(title, QLatin1String(URL_BUGTRACKER)); + m_ui->introLabel->setText(introLabelContents); + setWindowTitle(title); QString revision; #ifdef IDE_REVISION diff --git a/src/tools/qtcreatorcrashhandler/crashhandlerdialog.h b/src/tools/qtcreatorcrashhandler/crashhandlerdialog.h index 09cbd203b50..fc9ff7921ad 100644 --- a/src/tools/qtcreatorcrashhandler/crashhandlerdialog.h +++ b/src/tools/qtcreatorcrashhandler/crashhandlerdialog.h @@ -33,6 +33,7 @@ #include QT_BEGIN_NAMESPACE +class QString; namespace Ui { class CrashHandlerDialog; } @@ -45,11 +46,12 @@ class CrashHandlerDialog : public QDialog Q_OBJECT public: - explicit CrashHandlerDialog(CrashHandler *handler, QWidget *parent = 0); + explicit CrashHandlerDialog(CrashHandler *handler, const QString &signalName, + QWidget *parent = 0); ~CrashHandlerDialog(); public: - void setApplicationInfo(); + void setApplicationInfo(const QString &signalName); void appendDebugInfo(const QString &chunk); void selectLineWithContents(const QString &text); void setToFinalState(); diff --git a/src/tools/qtcreatorcrashhandler/crashhandlersetup.cpp b/src/tools/qtcreatorcrashhandler/crashhandlersetup.cpp index f0c51be663e..cc48afa7310 100644 --- a/src/tools/qtcreatorcrashhandler/crashhandlersetup.cpp +++ b/src/tools/qtcreatorcrashhandler/crashhandlersetup.cpp @@ -58,7 +58,7 @@ static const char *crashHandlerPathC; static void *signalHandlerStack; -extern "C" void signalHandler(int /*signal*/) +extern "C" void signalHandler(int signal) { #ifdef Q_WS_X11 // Kill window since it's frozen anyway. @@ -70,7 +70,7 @@ extern "C" void signalHandler(int /*signal*/) case -1: // error break; case 0: // child - execl(crashHandlerPathC, crashHandlerPathC, (char *) 0); + execl(crashHandlerPathC, crashHandlerPathC, strsignal(signal), (char *) 0); _exit(EXIT_FAILURE); default: // parent waitpid(pid, 0, 0); @@ -117,8 +117,10 @@ void setupCrashHandler() sa.sa_flags = SA_RESETHAND | SA_NODEFER | SA_ONSTACK; const int signalsToHandle[] = { SIGILL, SIGFPE, SIGSEGV, SIGBUS, 0 }; for (int i = 0; signalsToHandle[i]; ++i) { - if (sigaction(signalsToHandle[i], &sa, 0) == -1 ) - qWarning("Warning: Failed to install signal handler for SIGILL (%s).", Q_FUNC_INFO); + if (sigaction(signalsToHandle[i], &sa, 0) == -1 ) { + qWarning("Warning: Failed to install signal handler for signal \"%s\" (%s).", + strsignal(signalsToHandle[i]), Q_FUNC_INFO); + } } #endif // BUILD_CRASH_HANDLER } diff --git a/src/tools/qtcreatorcrashhandler/main.cpp b/src/tools/qtcreatorcrashhandler/main.cpp index 3bc5d76334a..623520cf228 100644 --- a/src/tools/qtcreatorcrashhandler/main.cpp +++ b/src/tools/qtcreatorcrashhandler/main.cpp @@ -41,6 +41,8 @@ #include #include +// Called by signal handler of qtcreator. +// Usage: $0 int main(int argc, char *argv[]) { QApplication app(argc, argv); @@ -51,15 +53,15 @@ int main(int argc, char *argv[]) Q_PID parentPid = getppid(); QString parentExecutable = QFile::symLinkTarget(QString::fromLatin1("/proc/%1/exe") .arg(QString::number(parentPid))); - if (argc > 1 || !parentExecutable.contains("qtcreator")) { + if (argc > 2 || !parentExecutable.contains("qtcreator")) { QTextStream err(stderr); err << QString::fromLatin1("This crash handler will be called by Qt Creator itself. " - "Don't call this manually.\n"); + "Do not call this manually.\n"); return EXIT_FAILURE; } // Run. - CrashHandler *crashHandler = new CrashHandler(parentPid); + CrashHandler *crashHandler = new CrashHandler(parentPid, app.arguments().at(1)); crashHandler->run(); return app.exec();