spark-qt-research/Components/CrashStackTrace/handler.cpp
2021-05-11 21:28:36 +08:00

66 lines
2.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 只使用GCC编译时则使用 -g -rdynamic选项
* CMake项目需分别使用add_compile_options(-g) add_link_options(-rdynamic)
* 否则获取调用栈时不能得到函数名
* 该配置仅支持GCC+Linux平台
*/
#include <execinfo.h>
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);
}