66 lines
2.7 KiB
C++
66 lines
2.7 KiB
C++
/*
|
||
* 只使用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);
|
||
} |