/* * 只使用GCC编译时,则使用 -g -rdynamic选项 * CMake项目需分别使用add_compile_options(-g) add_link_options(-rdynamic) * 否则获取调用栈时不能得到函数名 * 该配置仅支持GCC+Linux平台 */ #include QString WriteStackTrace(const QString &aStackTrace) { QString path = QDir::homePath() + "/.local/share/spark-store/crash/"; QFile StackTraceFile; if(!QDir().exists(path)) if(!QDir().mkpath(path)) return QObject::tr("Stack trace directory %1 cannot be created. " "Stack trace wasn't saved.").arg(path); path += QString::number(QDateTime::currentDateTimeUtc().toSecsSinceEpoch()); while(QFile::exists(path)) path += "_"; StackTraceFile.setFileName(path); StackTraceFile.open(QIODevice::WriteOnly); if(StackTraceFile.isOpen() && StackTraceFile.isWritable()) { QTextStream StackTraceWriter; StackTraceWriter.setDevice(&StackTraceFile); StackTraceWriter << QDateTime::currentDateTime().toLocalTime().toString() << "\n\n"; StackTraceWriter << aStackTrace; StackTraceFile.close(); return QObject::tr("Stack trace written to \"%1\".").arg(path); } return QObject::tr("Stack trace file %1 cannot be opened. " "Stack trace wasn't saved.").arg(path); } void CrashSignalHandler(int sig) { QString msg("Program has received signal %1 during normal execution.\n\n"); switch(sig) { case SIGSEGV: msg = msg.arg(QObject::tr("\"SIGSEGV\" (Segmentation fault)")); goto CRASH; case SIGFPE: msg = msg.arg(QObject::tr("\"SIGFPE\" (Arithmetic exception)")); goto CRASH; case SIGABRT: msg = msg.arg(QObject::tr("\"SIGABRT\" (Abort)")); CRASH: { void* TraceStack[StackTraceArraySize]; int StackTraceSize = backtrace(TraceStack, StackTraceArraySize); auto TraceTextArray = backtrace_symbols(TraceStack, StackTraceArraySize); msg += QString(QObject::tr("Stack trace:\n")); for(int i = 0; i < StackTraceSize; i++) msg += QString::number(i) + "> " + QString(TraceTextArray[i]) + '\n'; msg += "\n\nSpark Store cannot continue.\n\n"; msg += WriteStackTrace(msg); QMessageBox::critical(nullptr, QObject::tr("Spark Store Crashed"), msg); exit(2); } default: SpkLog::Error(QObject::tr("Unknown signal %1 received in crash handler. " "Program internals may be corrupted. Please decide if you want " "to continue execution.").arg(sig), true); }