当前位置: 首页 > 科技观察

Linux+Windows:程序崩溃时,如何获取C++代码中的函数调用堆栈信息

时间:2023-03-12 06:15:05 科技观察

1.前言Crash是程序执行过程中一个非常严重的问题。一般在测试阶段应该排除这些问题,但总会有漏网之鱼,被带到发布阶段。因此,程序的日志系统需要检测到这种情况,获取代码崩溃时的函数调用堆栈信息,为调试提供有效信息。这篇文章理论知识很少,直接分享两段代码:如何在Linux和Windows这两个平台上使用C++抓取函数调用栈中的信息。二、linux平台1、注册异常信号的处理函数需要处理哪些异常信号#include#include#includeconststd::mapSignals={{SIGINT,"SIGINT"},{SIGABRT,"SIGABRT"},{SIGFPE,"SIGFPE"},{SIGILL,"SIGILL"},{SIGSEGV,"SIGSEGV"}//添加其他信号};注册信号处理函数structsgactionaction;sigemptyset(&action.sa_mask);action.sa_sigaction=&sigHandler;action.sa_flags=SA_SIGINFO;for(constauto&sigPair:Signals){if(sigaction(sigPair.first,&action,NULL)<0)fprintf(stderr“错误:sigactionfailed!\n”);}2。捕获异常并获取函数调用堆栈信息数组,大小);std::ostringstreammoss;for(inti=0;i#includeSetUnhandledExceptionFilter(exceptionHandler);2.捕获异常,获取函数调用栈信息voidexceptionHandler(LPEXCEPTION_POINTERSinfo){CONTEXT*context=info->ContextRecord;std::shared_ptrRaiiSysCleaner(nullptr,[&](void*){SymCleanup(GetCurrentProcess());});constsize_tdumpSize=64;std::矢量frameVector(dumpSize);DWORDmachine_type=0;STACKFRAME64frame={};frame.AddrPC.Mode=AddrModeFlat;frame.AddrFrame.Mode=AddrModeFlat;frame.AddrStack.Mode=AddrModeFlat;#ifdef_M_IX86frame.AddrPC.Offset=context->Eip;frame.AddrFrame.Offset=上下文->Ebp;frame.AddrStack.Offset=上下文->Esp;machine_type=IMAGE_FILE_MACHINE_I386;#elif_M_X64frame.AddrPC.Offset=上下文->Rip;frame.AddrFrame.Offset=上下文->Rbp;frame.AddrStack.Offset=context->Rsp;machine_type=IMAGE_FILE_MACHINE_AMD64;#elif_M_IA64frame.AddrPC.Offset=context->StIIP;frame.AddrFrame.Offset=context->IntSp;frame.AddrStack.Offset=context->IntSp;machine_type=IMAGE_FILE_MACHINE_IA64;frame.AddrBStore.Offset=context.RsBSP;frame.AddrBStore.Mode=AddrModeF纬度;#elseframe.AddrPC.Offset=context->Eip;frame.AddrFrame.Offset=context->Ebp;frame.AddrStack.Offset=context->Esp;machine_type=IMAGE_FILE_MACHINE_I386;#endiffor(size_tindex=0;index