windows / c:如何从信号处理程序中获取有用的堆栈跟踪?
发布时间:2020-12-14 05:44:36 所属栏目:Windows 来源:网络整理
导读:我有一个 Windows / C应用程序(使用JUCE),我想在应用程序崩溃时将堆栈跟踪转储到文件中.在我的初始化代码中,我得到了: signal(SIGABRT,abortHandler);signal(SIGSEGV,abortHandler);signal(SIGILL,abortHandler);signal(SIGFPE,abortHandler); 然后我的处理
我有一个
Windows / C应用程序(使用JUCE),我想在应用程序崩溃时将堆栈跟踪转储到文件中.在我的初始化代码中,我得到了:
signal(SIGABRT,abortHandler); signal(SIGSEGV,abortHandler); signal(SIGILL,abortHandler); signal(SIGFPE,abortHandler); 然后我的处理程序看起来像: void abortHandler(int signum) { juce::File log("stacktrace.txt"); log.appendText(juce::SystemStats::getStackBacktrace()); exit(signum); } 但是,生成的堆栈跟踪不是发生崩溃的线程: 0: AudulusDebug32: juce::SystemStats::getStackBacktrace + 0x7f 1: AudulusDebug32: abortHandler + 0x61 2: AudulusDebug32: _XcptFilter + 0x1e3 3: AudulusDebug32: __tmainCRTStartup + 0x15f 4: AudulusDebug32: WinMainCRTStartup + 0xd 5: BaseThreadInitThunk + 0xe 6: RtlInitializeExceptionChain + 0x84 7: RtlInitializeExceptionChain + 0x5a 在内部,getStackBacktrace执行以下操作: HANDLE process = GetCurrentProcess(); SymInitialize (process,nullptr,TRUE); void* stack[128]; int frames = (int) CaptureStackBackTrace (0,numElementsInArray (stack),stack,nullptr); 有没有办法让崩溃发生的线程(或所有线程)获得堆栈跟踪? 解决方法
正如@HansPassant建议的那样,我的解决方案是:
SetUnhandledExceptionFilter(TopLevelExceptionHandler); 在TopLevelExceptionHandler中,我使用StackWalk64而不是调用CaptureStackBackTrace,它允许您指定要移动的堆栈(而不是仅假设当前堆栈). 这是代码: LONG WINAPI TopLevelExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo) { std::ofstream f; f.open("stacktrace.txt",std::ios::out | std::ios::trunc); HANDLE process = GetCurrentProcess(); SymInitialize(process,NULL,TRUE); // StackWalk64() may modify context record passed to it,so we will // use a copy. CONTEXT context_record = *pExceptionInfo->ContextRecord; // Initialize stack walking. STACKFRAME64 stack_frame; memset(&stack_frame,sizeof(stack_frame)); #if defined(_WIN64) int machine_type = IMAGE_FILE_MACHINE_AMD64; stack_frame.AddrPC.Offset = context_record.Rip; stack_frame.AddrFrame.Offset = context_record.Rbp; stack_frame.AddrStack.Offset = context_record.Rsp; #else int machine_type = IMAGE_FILE_MACHINE_I386; stack_frame.AddrPC.Offset = context_record.Eip; stack_frame.AddrFrame.Offset = context_record.Ebp; stack_frame.AddrStack.Offset = context_record.Esp; #endif stack_frame.AddrPC.Mode = AddrModeFlat; stack_frame.AddrFrame.Mode = AddrModeFlat; stack_frame.AddrStack.Mode = AddrModeFlat; juce::HeapBlock<SYMBOL_INFO> symbol; symbol.calloc(sizeof(SYMBOL_INFO) + 256,1); symbol->MaxNameLen = 255; symbol->SizeOfStruct = sizeof(SYMBOL_INFO); while (StackWalk64(machine_type,GetCurrentProcess(),GetCurrentThread(),&stack_frame,&context_record,&SymFunctionTableAccess64,&SymGetModuleBase64,NULL)) { DWORD64 displacement = 0; if (SymFromAddr(process,(DWORD64)stack_frame.AddrPC.Offset,&displacement,symbol)) { IMAGEHLP_MODULE64 moduleInfo; juce::zerostruct(moduleInfo); moduleInfo.SizeOfStruct = sizeof(moduleInfo); if (::SymGetModuleInfo64(process,symbol->ModBase,&moduleInfo)) f << moduleInfo.ModuleName << ": "; f << symbol->Name << " + 0x" << String::toHexString((juce::int64)displacement) << std::endl; } } return EXCEPTION_CONTINUE_SEARCH; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- 如何在Powershell中编辑Windows应用商店应用的settings.dat
- windows-server-2008 – 即使添加了防火墙例外,Windows 200
- Windows上的PuTTY替代方案:更好的保存会话组织
- Win10远程桌面 出现 身份验证错误,要求的函数不受支持,这
- 为什么使用其他用户通过PowerShell创建的每周任务失败,错误
- Windows Server2008搭建Exchang2010 Server
- win快捷键
- SMBv2和Windows 7
- windows-server-2003 – Windows 2003 ODBC问题 – 错误100
- azure – 如何在最新的Microsoft.IdentityModel.Clients.Ac