From 5c8a4b3912556076ffaedcd00608c23dd6ece654 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Sun, 13 Dec 2015 18:14:12 +0800 Subject: [PATCH 1/3] Simplify signal handler Try to use signal-safe functions as much as possible Closes #3995 Define sys_signame[] ourselves on linux --- src/app/main.cpp | 96 +++++++++++++++++++++--------------------------- 1 file changed, 42 insertions(+), 54 deletions(-) diff --git a/src/app/main.cpp b/src/app/main.cpp index 94e16bcc7..83b3ab89f 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -79,10 +79,15 @@ Q_IMPORT_PLUGIN(qico) // Signal handlers #if defined(Q_OS_UNIX) || defined(STACKTRACE_WIN) -void sigintHandler(int); -void sigtermHandler(int); -void sigsegvHandler(int); -void sigabrtHandler(int); +void sigNormalHandler(int signum); +void sigAbnormalHandler(int signum); +// sys_signame[] is only defined in BSD +const char *sysSigName[] = { + "", "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGTRAP", "SIGABRT", "SIGBUS", "SIGFPE", "SIGKILL", + "SIGUSR1", "SIGSEGV", "SIGUSR2", "SIGPIPE", "SIGALRM", "SIGTERM", "SIGSTKFLT", "SIGCHLD", "SIGCONT", "SIGSTOP", + "SIGTSTP", "SIGTTIN", "SIGTTOU", "SIGURG", "SIGXCPU", "SIGXFSZ", "SIGVTALRM", "SIGPROF", "SIGWINCH", "SIGIO", + "SIGPWR", "SIGUNUSED" +}; #endif struct QBtCommandLineParameters @@ -240,10 +245,10 @@ int main(int argc, char *argv[]) #endif #if defined(Q_OS_UNIX) || defined(STACKTRACE_WIN) - signal(SIGABRT, sigabrtHandler); - signal(SIGTERM, sigtermHandler); - signal(SIGINT, sigintHandler); - signal(SIGSEGV, sigsegvHandler); + signal(SIGINT, sigNormalHandler); + signal(SIGTERM, sigNormalHandler); + signal(SIGABRT, sigAbnormalHandler); + signal(SIGSEGV, sigAbnormalHandler); #endif return app->exec(params.torrents); @@ -303,58 +308,41 @@ QBtCommandLineParameters parseCommandLine() } #if defined(Q_OS_UNIX) || defined(STACKTRACE_WIN) -void sigintHandler(int) +void sigNormalHandler(int signum) { - signal(SIGINT, 0); - qDebug("Catching SIGINT, exiting cleanly"); - qApp->exit(); -} - -void sigtermHandler(int) -{ - signal(SIGTERM, 0); - qDebug("Catching SIGTERM, exiting cleanly"); - qApp->exit(); -} - -void sigsegvHandler(int) -{ - signal(SIGABRT, 0); - signal(SIGSEGV, 0); #if !defined Q_OS_WIN && !defined Q_OS_HAIKU - std::cerr << "\n\n*************************************************************\n"; - std::cerr << "Catching SIGSEGV, please report a bug at http://bug.qbittorrent.org\nand provide the following backtrace:\n"; - std::cerr << "qBittorrent version: " << VERSION << std::endl; - print_stacktrace(); -#else + const char str1[] = "Catching signal: "; + const char *sigName = sysSigName[signum]; + const char str2[] = "\nExiting cleanly\n"; + write(STDERR_FILENO, str1, strlen(str1)); + write(STDERR_FILENO, sigName, strlen(sigName)); + write(STDERR_FILENO, str2, strlen(str2)); +#endif // !defined Q_OS_WIN && !defined Q_OS_HAIKU + signal(signum, SIG_DFL); + qApp->exit(); // unsafe, but exit anyway +} + +void sigAbnormalHandler(int signum) +{ +#if !defined Q_OS_WIN && !defined Q_OS_HAIKU + const char str1[] = "\n\n*************************************************************\nCatching signal: "; + const char *sigName = sysSigName[signum]; + const char str2[] = "\nPlease file a bug report at http://bug.qbittorrent.org and provide the following information:\n\n" + "qBittorrent version: " VERSION "\n"; + write(STDERR_FILENO, str1, strlen(str1)); + write(STDERR_FILENO, sigName, strlen(sigName)); + write(STDERR_FILENO, str2, strlen(str2)); + print_stacktrace(); // unsafe +#endif // !defined Q_OS_WIN && !defined Q_OS_HAIKU #ifdef STACKTRACE_WIN - StraceDlg dlg; + StraceDlg dlg; // unsafe dlg.setStacktraceString(straceWin::getBacktrace()); dlg.exec(); -#endif -#endif - raise(SIGSEGV); +#endif // STACKTRACE_WIN + signal(signum, SIG_DFL); + raise(signum); } - -void sigabrtHandler(int) -{ - signal(SIGABRT, 0); - signal(SIGSEGV, 0); -#if !defined Q_OS_WIN && !defined Q_OS_HAIKU - std::cerr << "\n\n*************************************************************\n"; - std::cerr << "Catching SIGABRT, please report a bug at http://bug.qbittorrent.org\nand provide the following backtrace:\n"; - std::cerr << "qBittorrent version: " << VERSION << std::endl; - print_stacktrace(); -#else -#ifdef STACKTRACE_WIN - StraceDlg dlg; - dlg.setStacktraceString(straceWin::getBacktrace()); - dlg.exec(); -#endif -#endif - raise(SIGABRT); -} -#endif +#endif // defined(Q_OS_UNIX) || defined(STACKTRACE_WIN) #ifndef DISABLE_GUI void showSplashScreen() From ef75ae4aeecd35ca179b3defb8d12d36c5dfec26 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Sun, 13 Dec 2015 20:42:02 +0800 Subject: [PATCH 2/3] Try to concat most of the string at compile time The lesser unsafe code in signal handler the better Add license --- src/app/stacktrace_win_dlg.h | 91 ++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 31 deletions(-) diff --git a/src/app/stacktrace_win_dlg.h b/src/app/stacktrace_win_dlg.h index 0040c7da5..eb4604477 100644 --- a/src/app/stacktrace_win_dlg.h +++ b/src/app/stacktrace_win_dlg.h @@ -1,51 +1,80 @@ +/* + * Bittorrent Client using Qt and libtorrent. + * Copyright (C) 2015 The qBittorrent project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + */ + #ifndef STACKTRACE_WIN_DLG_H #define STACKTRACE_WIN_DLG_H -#include -#include +#include +#include #include "boost/version.hpp" #include "libtorrent/version.hpp" #include "ui_stacktrace_win_dlg.h" -class StraceDlg: public QDialog, private Ui::errorDialog +class StraceDlg : public QDialog, private Ui::errorDialog { Q_OBJECT public: - StraceDlg(QWidget* parent = 0): QDialog(parent) + StraceDlg(QWidget* parent = 0) + : QDialog(parent) { setupUi(this); } - ~StraceDlg() - { - } - void setStacktraceString(const QString& trace) { - QString htmlStr; - QTextStream outStream(&htmlStr); - outStream << "

" << - "qBittorrent has crashed" << - "

" << - "" << - "

" << - "Please report a bug at " << - "http://bugs.qbittorrent.org" << - " and provide the following backtrace." << - "

" << - "
" << - "


" << - "

qBittorrent version: " << VERSION << - "
Libtorrent version: " << LIBTORRENT_VERSION << - "
Qt version: " << QT_VERSION_STR << - "
Boost version: " << QString::number(BOOST_VERSION / 100000) << '.' << - QString::number((BOOST_VERSION / 100) % 1000) << '.' << - QString::number(BOOST_VERSION % 100) << "


" - "
" <<
-            trace <<
-            "
" << - "



"; + // try to call Qt function as less as possible + const int boostVerMajor = BOOST_VERSION / 100000; + const int boostVerMinor = ((BOOST_VERSION / 100) % 1000); + const int boostVerSubMin = BOOST_VERSION % 100; + QString htmlStr = QString( + "

" + "qBittorrent has crashed" + "

" + "

" + "Please file a bug report at " + "http://bugs.qbittorrent.org " + "and provide the following information:" + "

" + "


" + "

" + "qBittorrent version: " VERSION "
" + "Libtorrent version: " LIBTORRENT_VERSION "
" + "Qt version: " QT_VERSION_STR "
" + "Boost version: %1.%2.%3" + "


" + "
%4
" + "



") + .arg(boostVerMajor) + .arg(boostVerMinor) + .arg(boostVerSubMin) + .arg(trace); errorText->setHtml(htmlStr); } From 4a3d9029d1995f41bd0d723007e33d58492a4412 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Sun, 13 Dec 2015 22:01:53 +0800 Subject: [PATCH 3/3] Add #include guard --- src/app/stacktrace_win.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/app/stacktrace_win.h b/src/app/stacktrace_win.h index 8d1eced49..bfd748e8f 100644 --- a/src/app/stacktrace_win.h +++ b/src/app/stacktrace_win.h @@ -18,6 +18,9 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#ifndef STACKTRACE_WIN_H +#define STACKTRACE_WIN_H + #include #include #include @@ -266,3 +269,5 @@ const QString straceWin::getBacktrace() #pragma warning(pop) #pragma optimize("g", on) #endif + +#endif // STACKTRACE_WIN_H