2025-04-15 21:51:09 +08:00
|
|
|
《Linux部分》
|
2025-04-15 22:35:18 +08:00
|
|
|
【Linux => Debug模式】
|
2025-04-15 21:51:09 +08:00
|
|
|
测试:https://github.com/bombela/backward-cpp
|
2025-04-15 22:35:18 +08:00
|
|
|
仅头文件的库,配合#define BACKWARD_HAS_BFD 1和sudo apt install binutils-dev
|
2025-04-15 21:51:09 +08:00
|
|
|
可以实现Debug下精准找点。
|
|
|
|
也有apt-get install libdw-dev(#define BACKWARD_HAS_DW 1)和
|
|
|
|
apt-get install libdwarf-dev(#define BACKWARD_HAS_DWARF 1)这两个没测试。
|
|
|
|
|
|
|
|
使用方法为:
|
|
|
|
#define BACKWARD_HAS_BFD 1
|
|
|
|
#include "backward.hpp"
|
|
|
|
#include <csignal>
|
|
|
|
#include <iostream>
|
|
|
|
#include <thread>
|
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
void sig_handler(int sig)
|
|
|
|
{
|
|
|
|
backward::StackTrace st;
|
|
|
|
st.load_here(32);
|
|
|
|
backward::Printer p;
|
|
|
|
p.print(st);
|
|
|
|
|
|
|
|
std::ofstream fs("stacktrace.log");
|
|
|
|
p.print(st, fs);
|
|
|
|
fs.close();
|
|
|
|
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void th_sim()
|
|
|
|
{
|
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(5));
|
|
|
|
// throw "Erro Auto";
|
|
|
|
int* p = nullptr;
|
|
|
|
*p = 33;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
signal(SIGSEGV, sig_handler);
|
|
|
|
signal(SIGABRT, sig_handler);
|
|
|
|
signal(SIGFPE, sig_handler);
|
|
|
|
|
|
|
|
std::thread t(th_sim);
|
|
|
|
std::cout << "Done" << std::endl;
|
|
|
|
t.join();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
编译链接:target_link_libraries(dmeo PRIVATE bfd dl)
|
|
|
|
|
|
|
|
《Windows部分》
|
2025-04-15 22:35:18 +08:00
|
|
|
【Windows => Debug模式】
|
2025-04-15 21:51:09 +08:00
|
|
|
#include "backward.hpp"
|
|
|
|
#include <windows.h>
|
|
|
|
使用方法:
|
|
|
|
|
|
|
|
LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS* exception)
|
|
|
|
{
|
|
|
|
backward::StackTrace st;
|
|
|
|
st.load_from(exception->ContextRecord);
|
|
|
|
backward::Printer p;
|
|
|
|
|
|
|
|
// 输出到控制台
|
|
|
|
p.print(st, std::cerr);
|
|
|
|
|
|
|
|
// 输出到文件
|
|
|
|
std::ofstream fs("stacktrace.log");
|
|
|
|
p.print(st, fs);
|
|
|
|
fs.close();
|
|
|
|
|
|
|
|
return EXCEPTION_EXECUTE_HANDLER; // 终止程序
|
|
|
|
}
|
|
|
|
|
|
|
|
显示初始化:backward::SignalHandling sh;而且必须在SetUnhandledExceptionFilter(ExceptionHandler); 后面。
|
|
|
|
|
|
|
|
如下:
|
|
|
|
#include <iostream>
|
|
|
|
#include <thread>
|
|
|
|
#include "backward.hpp"
|
|
|
|
#include <windows.h>
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS* exception)
|
|
|
|
{
|
|
|
|
backward::StackTrace st;
|
|
|
|
st.load_from(exception->ContextRecord);
|
|
|
|
backward::Printer p;
|
|
|
|
|
|
|
|
// 输出到控制台
|
|
|
|
p.print(st, std::cerr);
|
|
|
|
|
|
|
|
// 输出到文件
|
|
|
|
std::ofstream fs("stacktrace.log");
|
|
|
|
p.print(st, fs);
|
|
|
|
fs.close();
|
|
|
|
|
|
|
|
return EXCEPTION_EXECUTE_HANDLER; // 终止程序
|
|
|
|
}
|
|
|
|
|
|
|
|
void th_sim()
|
|
|
|
{
|
|
|
|
std::this_thread::sleep_for(std::chrono::seconds(5));
|
|
|
|
// throw "Erro Auto";
|
|
|
|
int* p = nullptr;
|
|
|
|
*p = 33;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
SetUnhandledExceptionFilter(ExceptionHandler); // 注册全局异常处理
|
|
|
|
backward::SignalHandling sh;
|
|
|
|
// std::set_terminate(terminate_handler);
|
|
|
|
std::thread t(th_sim);
|
|
|
|
std::cout << "Done" << std::endl;
|
|
|
|
t.join();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
编译链接:
|
2025-04-15 22:35:18 +08:00
|
|
|
target_link_libraries(dumpdemo PRIVATE DbgHelp)
|
|
|
|
【Windows => Release模式】
|
|
|
|
实际测试,如果想生成dmp文件,就不能使用backward库(两者选一个)(不使用backward::SignalHandling sh;)。
|
|
|
|
void CreateMiniDump(EXCEPTION_POINTERS* exception) {
|
|
|
|
HANDLE hFile = CreateFile("crash114.dmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if (hFile == INVALID_HANDLE_VALUE) {
|
|
|
|
return;
|
|
|
|
};
|
|
|
|
MINIDUMP_EXCEPTION_INFORMATION info;
|
|
|
|
info.ThreadId = GetCurrentThreadId();
|
|
|
|
info.ExceptionPointers = exception;
|
|
|
|
info.ClientPointers = TRUE;
|
|
|
|
MiniDumpWriteDump(
|
|
|
|
GetCurrentProcess(), GetCurrentProcessId(), hFile,
|
|
|
|
MiniDumpNormal, &info, NULL, NULL
|
|
|
|
);
|
|
|
|
CloseHandle(hFile);
|
|
|
|
}
|
|
|
|
使用backward堆栈信息打印有限,如下(测试代码见上方):
|
|
|
|
Done
|
|
|
|
Stack trace (most recent call last):
|
|
|
|
#3 Object "", at 00007FFBD4A4E8D7, in BaseThreadInitThunk
|
|
|
|
#2 Object "", at 00007FFBD31C37B0, in wcsrchr
|
|
|
|
试图访问无效的地址。
|
|
|
|
|
|
|
|
#1 Object "", at 00007FF691A2208B, in ??
|
|
|
|
试图访问无效的地址。
|
|
|
|
|
|
|
|
#0 Object "", at 00007FF691A27EC2, in ??
|
|
|
|
而使用WinDbg分析Dump文件,信息如下:
|
|
|
|
FILE_IN_CAB: crash114.dmp
|
|
|
|
|
|
|
|
CONTEXT: (.ecxr)
|
|
|
|
rax=0000000000000000 rbx=0000019f92279e60 rcx=00000018c2d828f9
|
|
|
|
rdx=00000018ca1b2b0e rsi=00004e94914f0000 rdi=000009ac1b967bb8
|
|
|
|
rip=00007ff7b2f41682 rsp=00000084c57ff970 rbp=0000000000000000
|
|
|
|
r8=0000000000000083 r9=000000007ffe7000 r10=0000000000000001
|
|
|
|
r11=fffffffff8bcfdeb r12=0000000000000000 r13=0000000000000000
|
|
|
|
r14=b2f4fc0794908cf3 r15=0000000000000000
|
|
|
|
iopl=0 nv up ei pl zr na po nc
|
|
|
|
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
|
|
|
|
dumpdemo+0x1682:
|
|
|
|
00007ff7`b2f41682 c70021000000 mov dword ptr [rax],21h ds:00000000`00000000=????????
|
|
|
|
Resetting default scope
|
|
|
|
|
|
|
|
EXCEPTION_RECORD: (.exr -1)
|
|
|
|
ExceptionAddress: 00007ff7b2f41682 (dumpdemo+0x0000000000001682)
|
|
|
|
ExceptionCode: c0000005 (Access violation)
|
|
|
|
ExceptionFlags: 00000000
|
|
|
|
NumberParameters: 2
|
|
|
|
Parameter[0]: 0000000000000001
|
|
|
|
Parameter[1]: 0000000000000000
|
|
|
|
Attempt to write to address 0000000000000000
|
|
|
|
|
|
|
|
PROCESS_NAME: dumpdemo.exe
|
|
|
|
|
|
|
|
WRITE_ADDRESS: 0000000000000000
|
|
|
|
|
|
|
|
ERROR_CODE: (NTSTATUS) 0xc0000005 - 0x%p 0x%p %s
|
|
|
|
|
|
|
|
EXCEPTION_CODE_STR: c0000005
|
|
|
|
|
|
|
|
EXCEPTION_PARAMETER1: 0000000000000001
|
|
|
|
|
|
|
|
EXCEPTION_PARAMETER2: 0000000000000000
|
|
|
|
|
|
|
|
STACK_TEXT:
|
|
|
|
00000084`c57ff970 00007ff7`b2f4126b : 000009aa`f19089b8 0000019f`92279e60 00000000`00000000 00000000`00000000 : dumpdemo+0x1682
|
|
|
|
00000084`c57ff9b0 00007ffb`d31c37b0 : 0000019f`92275720 00000000`00000000 00000000`00000000 00000000`00000000 : dumpdemo+0x126b
|
|
|
|
00000084`c57ff9e0 00007ffb`d4a4e8d7 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ucrtbase!thread_start<unsigned int (__cdecl*)(void *),1>+0x30
|
|
|
|
00000084`c57ffa10 00007ffb`d5b314fc : 00000000`00000000 00000000`00000000 000004f0`fffffb30 000004d0`fffffb30 : kernel32!BaseThreadInitThunk+0x17
|
|
|
|
00000084`c57ffa40 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x2c
|
|
|
|
|
|
|
|
|
|
|
|
STACK_COMMAND: ~4s; .ecxr ; kb
|
|
|
|
|
|
|
|
SYMBOL_NAME: dumpdemo+1682
|
|
|
|
|
|
|
|
MODULE_NAME: dumpdemo
|
|
|
|
|
|
|
|
IMAGE_NAME: dumpdemo.exe
|
|
|
|
|
|
|
|
FAILURE_BUCKET_ID: NULL_POINTER_WRITE_c0000005_dumpdemo.exe!Unknown
|
|
|
|
|
|
|
|
OS_VERSION: 10.0.26100.1
|
|
|
|
|
|
|
|
BUILDLAB_STR: ge_release
|
|
|
|
|
|
|
|
OSPLATFORM_TYPE: x64
|
|
|
|
|
|
|
|
OSNAME: Windows 10
|
|
|
|
|
|
|
|
FAILURE_ID_HASH: {78a98d01-ecf2-dbb7-c5b9-5fb9cd0cc5e2}
|
|
|
|
|
|
|
|
Followup: MachineOwner
|
|
|
|
---------
|
|
|
|
|
|
|
|
0:004> .ecxr
|
|
|
|
rax=0000000000000000 rbx=0000019f92279e60 rcx=00000018c2d828f9
|
|
|
|
rdx=00000018ca1b2b0e rsi=00004e94914f0000 rdi=000009ac1b967bb8
|
|
|
|
rip=00007ff7b2f41682 rsp=00000084c57ff970 rbp=0000000000000000
|
|
|
|
r8=0000000000000083 r9=000000007ffe7000 r10=0000000000000001
|
|
|
|
r11=fffffffff8bcfdeb r12=0000000000000000 r13=0000000000000000
|
|
|
|
r14=b2f4fc0794908cf3 r15=0000000000000000
|
|
|
|
iopl=0 nv up ei pl zr na po nc
|
|
|
|
cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010246
|
|
|
|
dumpdemo+0x1682:
|
|
|
|
00007ff7`b2f41682 c70021000000 mov dword ptr [rax],21h ds:00000000`00000000=????????
|
|
|
|
0:004> kb
|
|
|
|
*** Stack trace for last set context - .thread/.cxr resets it
|
|
|
|
# RetAddr : Args to Child : Call Site
|
|
|
|
00 00007ff7`b2f4126b : 000009aa`f19089b8 0000019f`92279e60 00000000`00000000 00000000`00000000 : dumpdemo+0x1682
|
|
|
|
01 00007ffb`d31c37b0 : 0000019f`92275720 00000000`00000000 00000000`00000000 00000000`00000000 : dumpdemo+0x126b
|
|
|
|
02 00007ffb`d4a4e8d7 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ucrtbase!thread_start<unsigned int (__cdecl*)(void *),1>+0x30
|
|
|
|
03 00007ffb`d5b314fc : 00000000`00000000 00000000`00000000 000004f0`fffffb30 000004d0`fffffb30 : kernel32!BaseThreadInitThunk+0x17
|
|
|
|
04 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x2c
|