我是崩溃转储分析的新手。这是我的vmcore的bt -f
的输出,我希望看到它当时持有的函数foo
的参数的值。我有一台64位机器并浏览我发现的代码foo
只接受一个参数。无论如何,有没有办法知道哪个地址属于哪个参数。
#4 [ffff8807adfaf8c0] foobar at ffffffffa11c7c15 [foo]
ffff8807adfaf8c8: ffff881033e1d800 ffff8807adfaf8e8
ffff8807adfaf8d8: ffff8807adfaf938 ffffffffa11c7ce1
这是最后的寄存器值
RIP: 00007fa64fdfb907 RSP: 00007fff2a187ca0 RFLAGS: 00010246
RAX: 00000000000000a6 RBX: ffffffff8100b072 RCX: 00007fa6506f7390
RDX: 0000000000000000 RSI: 0000000000000000 RDI: 00007fa6508fe910
RBP: 00007fa6508fe8f0 R8: 00007fa6508fe930 R9: 0000000000000000
R10: 00007fff2a1884b0 R11: 0000000000000246 R12: 0000000000000000
R13: 0000000000000000 R14: 0000000000000000 R15: 00007fa6508fe990
ORIG_RAX: 00000000000000a6 CS: 0033 SS: 002b
答案 0 :(得分:3)
foobar()
的参数很可能在寄存器中传递,因此它可能根本不存在于任何存储器地址中。参数的类型将决定它是在寄存器中传递还是在内存中传递。
您在评论中提到该功能的原型是:
static void foobar(struct bar *b)
因此,第一个参数是常规的INTEGER类型(由x86_64 ABI定义;这包括指针)。要查找该指针参数的值,您需要查看从入口点到当前指令(即foo
处)的RIP
函数的反汇编。该值将传递给%rdi
中的函数。
但是,%rdi
中的值可能已在函数入口和转储发生的指令之间被覆盖或修改。在这种情况下,你可能需要做一些小侦探工作来倒退,找到最初传递的论据。
作为一般方法,我建议:
从入口点到显示的RIP
获取函数的反汇编。
查看该反汇编中%rdi
的使用方式。有没有修改%rdi
的内容?是否存在任何函数调用(它们本身可以覆盖%rdi
值)。如果没有,您的论点是00007fa6508fe910
如果%rdi
被修改,请查看是否已复制到另一个寄存器或保存在堆栈中。如果没有,请通过查看其反汇编来查看调用者如何生成该指针。