Jur*_*sic 5 stack stack-trace google-breakpad
我在项目中使用 Breakpad 来处理崩溃并生成堆栈跟踪。在堆栈跟踪中,函数调用 stackwalker 找到的信息有多种方式。这里描述的过程Finding_the_caller_frame:
他们之间有什么区别?更重要的是,它们如何在调试方面提供帮助?
Thread 0 (crashed)
0 test_google_breakpad!crash [test_breakpad.cpp : 17 + 0x4]
r4 = 0x00015530 r5 = 0xbea2cbe4 r6 = 0xffffff38 r7 = 0xbea2cb5c
r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 fp = 0x00000000
sp = 0xbea2cb50 lr = 0x00009025 pc = 0x00008f84
Found by: given as instruction pointer in context
1 test_google_breakpad!main [test_breakpad.cpp : 25 + 0x3]
r4 = 0x00015530 r5 = 0xbea2cbe4 r6 = 0xffffff38 r7 = 0xbea2cb5c
r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 fp = 0x00000000
sp = 0xbea2cb50 pc = 0x00009025
Found by: call frame info
2 libc.so + 0x164e5
r4 = 0x00008f64 r5 = 0xbea2cc34 r6 = 0x00000001 r7 = 0xbea2cc3c
r8 = 0x00000000 r9 = 0x00000000 r10 = 0x00000000 fp = 0x00000000
sp = 0xbea2cc18 pc = 0x400c34e7
Found by: call frame info
Run Code Online (Sandbox Code Playgroud)
指令指针方法意味着CPU寄存器已经指向函数的内存位置,因此不需要搜索函数。这是查找当前堆栈帧最简单、最可靠的方法。
接下来,使用调用帧技术,您可以通过查看堆栈内存中存储返回地址的位置来找到当前函数的调用者。这正是“返回”用来查找其返回目的地的技术。该技术可以被链接起来,因为之前的每个调用也将其返回值放入堆栈中。这是相当可靠的,但如果某些堆栈内存损坏(可能是堆栈溢出,可能是错误的指针写入)并且一个或多个返回地址被删除,则可能会失败。
最后,最不可靠的技术是仅在堆栈内存中搜索任何看起来像函数地址的内容。这可以帮助您从损坏的堆栈中恢复,但很难区分数据(包括函数指针!)和函数地址,因此这是猜测。不过,如果你找到了一个,如果你发现一些没有被废弃的堆栈,你通常可以链接回调用框架技术。