mirror of
https://github.com/feather-wallet/feather.git
synced 2024-12-22 19:49:28 +00:00
Linux: stack trace on crash
This commit is contained in:
parent
a7a06d8413
commit
7f07f98f92
7 changed files with 120 additions and 4 deletions
|
@ -26,6 +26,7 @@ option(PLATFORM_INSTALLER "Built-in updater fetches installer (windows-only)" OF
|
||||||
option(USE_DEVICE_TREZOR "Trezor support compilation" ON)
|
option(USE_DEVICE_TREZOR "Trezor support compilation" ON)
|
||||||
option(DONATE_BEG "Prompt donation window every once in a while" OFF)
|
option(DONATE_BEG "Prompt donation window every once in a while" OFF)
|
||||||
option(WITH_SCANNER "Enable webcam QR scanner" ON)
|
option(WITH_SCANNER "Enable webcam QR scanner" ON)
|
||||||
|
option(STACK_TRACE "Dump stack trace on crash (Linux only)" OFF)
|
||||||
|
|
||||||
list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_SOURCE_DIR}/cmake")
|
list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_SOURCE_DIR}/cmake")
|
||||||
include(CheckCCompilerFlag)
|
include(CheckCCompilerFlag)
|
||||||
|
@ -105,8 +106,8 @@ if(MINGW)
|
||||||
set(Boost_THREADAPI win32)
|
set(Boost_THREADAPI win32)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(Boost_USE_MULTITHREADED ON)
|
|
||||||
find_package(Boost 1.58 REQUIRED COMPONENTS
|
set(BOOST_COMPONENTS
|
||||||
system
|
system
|
||||||
filesystem
|
filesystem
|
||||||
thread
|
thread
|
||||||
|
@ -116,7 +117,15 @@ find_package(Boost 1.58 REQUIRED COMPONENTS
|
||||||
serialization
|
serialization
|
||||||
program_options
|
program_options
|
||||||
locale
|
locale
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(STACK_TRACE AND UNIX AND NOT APPLE)
|
||||||
|
list(APPEND BOOST_COMPONENTS
|
||||||
|
stacktrace_basic)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(Boost_USE_MULTITHREADED ON)
|
||||||
|
find_package(Boost 1.58 REQUIRED COMPONENTS ${BOOST_COMPONENTS})
|
||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
|
|
@ -22,7 +22,7 @@ $(package)_toolset_$(host_os)=gcc
|
||||||
$(package)_archiver_$(host_os)=$($(package)_ar)
|
$(package)_archiver_$(host_os)=$($(package)_ar)
|
||||||
$(package)_toolset_darwin=darwin
|
$(package)_toolset_darwin=darwin
|
||||||
$(package)_archiver_darwin=$($(package)_libtool)
|
$(package)_archiver_darwin=$($(package)_libtool)
|
||||||
$(package)_config_libraries=chrono,filesystem,program_options,system,thread,test,date_time,regex,serialization,locale
|
$(package)_config_libraries=chrono,filesystem,program_options,system,thread,test,date_time,regex,serialization,locale,stacktrace
|
||||||
$(package)_cxxflags=-std=c++17
|
$(package)_cxxflags=-std=c++17
|
||||||
$(package)_cxxflags_linux=-fPIC
|
$(package)_cxxflags_linux=-fPIC
|
||||||
$(package)_cxxflags_freebsd=-fPIC
|
$(package)_cxxflags_freebsd=-fPIC
|
||||||
|
|
|
@ -284,6 +284,7 @@ mkdir -p "$DISTSRC"
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
*linux*)
|
*linux*)
|
||||||
|
CMAKEVARS+=" -DSTACK_TRACE=ON"
|
||||||
case "$OPTIONS" in
|
case "$OPTIONS" in
|
||||||
tails)
|
tails)
|
||||||
CMAKEVARS+=" -DTOR_DIR=Off -DTOR_VERSION=Off"
|
CMAKEVARS+=" -DTOR_DIR=Off -DTOR_VERSION=Off"
|
||||||
|
|
|
@ -117,6 +117,13 @@ set_target_properties(feather PROPERTIES
|
||||||
LINK_FLAGS_RELEASE -s
|
LINK_FLAGS_RELEASE -s
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(STACK_TRACE)
|
||||||
|
message(STATUS "Stack Trace Enabled")
|
||||||
|
if (STATIC)
|
||||||
|
set_property(TARGET feather APPEND PROPERTY LINK_FLAGS "-Wl,--wrap=__cxa_throw")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
target_include_directories(feather PUBLIC
|
target_include_directories(feather PUBLIC
|
||||||
${CMAKE_BINARY_DIR}/src/feather_autogen/include
|
${CMAKE_BINARY_DIR}/src/feather_autogen/include
|
||||||
${CMAKE_SOURCE_DIR}/monero/include
|
${CMAKE_SOURCE_DIR}/monero/include
|
||||||
|
@ -186,6 +193,10 @@ if(PLATFORM_INSTALLER)
|
||||||
target_compile_definitions(feather PRIVATE PLATFORM_INSTALLER=1)
|
target_compile_definitions(feather PRIVATE PLATFORM_INSTALLER=1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(STACK_TRACE)
|
||||||
|
target_compile_definitions(feather PRIVATE STACK_TRACE=1)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(HAVE_SYS_PRCTL_H)
|
if(HAVE_SYS_PRCTL_H)
|
||||||
target_compile_definitions(feather PRIVATE HAVE_SYS_PRCTL_H=1)
|
target_compile_definitions(feather PRIVATE HAVE_SYS_PRCTL_H=1)
|
||||||
endif()
|
endif()
|
||||||
|
@ -290,6 +301,10 @@ if(DEPENDS AND APPLE)
|
||||||
${CMAKE_OSX_SYSROOT}/lib/darwin/libclang_rt.osx.a)
|
${CMAKE_OSX_SYSROOT}/lib/darwin/libclang_rt.osx.a)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(STACK_TRACE AND CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||||
|
target_link_libraries(feather -rdynamic)
|
||||||
|
endif()
|
||||||
|
|
||||||
install(TARGETS feather
|
install(TARGETS feather
|
||||||
DESTINATION ${CMAKE_INSTALL_PREFIX}
|
DESTINATION ${CMAKE_INSTALL_PREFIX}
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "WindowManager.h"
|
#include "WindowManager.h"
|
||||||
|
|
||||||
|
#include <QDialogButtonBox>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
@ -38,6 +39,8 @@ WindowManager::WindowManager(EventFilter *eventFilter)
|
||||||
|
|
||||||
this->initSkins();
|
this->initSkins();
|
||||||
|
|
||||||
|
this->showCrashLogs();
|
||||||
|
|
||||||
if (!config()->get(Config::firstRun).toBool() || TailsOS::detect() || WhonixOS::detect()) {
|
if (!config()->get(Config::firstRun).toBool() || TailsOS::detect() || WhonixOS::detect()) {
|
||||||
this->onInitialNetworkConfigured();
|
this->onInitialNetworkConfigured();
|
||||||
}
|
}
|
||||||
|
@ -410,6 +413,58 @@ void WindowManager::displayWalletErrorMessage(const QString &message) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowManager::showCrashLogs() {
|
||||||
|
QString crashLogPath{Config::defaultConfigDir().path() + "/crash_report.txt"};
|
||||||
|
QFile crashLogFile{crashLogPath};
|
||||||
|
|
||||||
|
if (!crashLogFile.exists()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool r = crashLogFile.open(QIODevice::ReadOnly);
|
||||||
|
if (!r) {
|
||||||
|
qWarning() << "Unable to open crash log file: " << crashLogPath;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextStream log(&crashLogFile);
|
||||||
|
QString logString = log.readAll();
|
||||||
|
crashLogFile.close();
|
||||||
|
|
||||||
|
bool renamed = false;
|
||||||
|
for (int i = 1; i < 999; i++) {
|
||||||
|
QString name{QString("/crash_report_%1.txt").arg(QString::number(i))};
|
||||||
|
if (crashLogFile.rename(Config::defaultConfigDir().path() + name)) {
|
||||||
|
renamed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!renamed) {
|
||||||
|
crashLogFile.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog dialog(nullptr);
|
||||||
|
dialog.setWindowTitle("Crash report");
|
||||||
|
|
||||||
|
QVBoxLayout layout;
|
||||||
|
QLabel msg{"Feather encountered an unrecoverable error.\n\nPlease send a copy of these logs to the developers. Logs are not automatically reported.\n"};
|
||||||
|
QTextEdit logs;
|
||||||
|
logs.setText(logString);
|
||||||
|
|
||||||
|
layout.addWidget(&msg);
|
||||||
|
layout.addWidget(&logs);
|
||||||
|
QDialogButtonBox buttons(QDialogButtonBox::Ok);
|
||||||
|
layout.addWidget(&buttons);
|
||||||
|
dialog.setLayout(&layout);
|
||||||
|
QObject::connect(&buttons, &QDialogButtonBox::accepted, [&dialog]{
|
||||||
|
dialog.close();
|
||||||
|
});
|
||||||
|
dialog.exec();
|
||||||
|
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
// ######################## DEVICE ########################
|
// ######################## DEVICE ########################
|
||||||
|
|
||||||
void WindowManager::onDeviceButtonRequest(quint64 code) {
|
void WindowManager::onDeviceButtonRequest(quint64 code) {
|
||||||
|
|
|
@ -69,6 +69,7 @@ private:
|
||||||
void buildTrayMenu();
|
void buildTrayMenu();
|
||||||
void startupWarning();
|
void startupWarning();
|
||||||
void showWarningMessageBox(const QString &title, const QString &message);
|
void showWarningMessageBox(const QString &title, const QString &message);
|
||||||
|
void showCrashLogs();
|
||||||
|
|
||||||
void quitAfterLastWindow();
|
void quitAfterLastWindow();
|
||||||
|
|
||||||
|
|
35
src/main.cpp
35
src/main.cpp
|
@ -12,6 +12,16 @@
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "utils/EventFilter.h"
|
#include "utils/EventFilter.h"
|
||||||
#include "WindowManager.h"
|
#include "WindowManager.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#if defined(Q_OS_LINUX) && defined(STACK_TRACE)
|
||||||
|
#define BOOST_STACKTRACE_LINK
|
||||||
|
#include <signal.h>
|
||||||
|
#include <boost/stacktrace.hpp>
|
||||||
|
#include <fstream>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -22,10 +32,35 @@
|
||||||
Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)
|
Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(Q_OS_LINUX) && defined(STACK_TRACE)
|
||||||
|
void signal_handler(int signum) {
|
||||||
|
::signal(signum, SIG_DFL);
|
||||||
|
std::stringstream keyStream;
|
||||||
|
keyStream << boost::stacktrace::stacktrace();
|
||||||
|
std::cout << keyStream.str();
|
||||||
|
|
||||||
|
// Write stack trace to disk
|
||||||
|
QString crashLogPath{Config::defaultConfigDir().path() + "/crash_report.txt"};
|
||||||
|
std::ofstream out(crashLogPath.toStdString());
|
||||||
|
out << keyStream.str();
|
||||||
|
out.close();
|
||||||
|
|
||||||
|
// Make a last ditch attempt to restart the application
|
||||||
|
QProcess::startDetached(qApp->arguments()[0], qApp->arguments());
|
||||||
|
|
||||||
|
::raise(SIGABRT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
Q_INIT_RESOURCE(assets);
|
Q_INIT_RESOURCE(assets);
|
||||||
|
|
||||||
|
#if defined(Q_OS_LINUX) && defined(STACK_TRACE)
|
||||||
|
::signal(SIGSEGV, &signal_handler);
|
||||||
|
::signal(SIGABRT, &signal_handler);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(HAS_TOR_BIN)
|
#if defined(HAS_TOR_BIN)
|
||||||
Q_INIT_RESOURCE(assets_tor);
|
Q_INIT_RESOURCE(assets_tor);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue