如何知道哪个地址属于Crash Dump中函数的哪个参数

时间:2015-11-26 05:33:32

标签: linux linux-kernel crash-dumps

我是崩溃转储分析的新手。这是我的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

1 个答案:

答案 0 :(得分:3)

foobar()的参数很可能在寄存器中传递,因此它可能根本不存在于任何存储器地址中。参数的类型将决定它是在寄存器中传递还是在内存中传递。

您在评论中提到该功能的原型是:

static void foobar(struct bar *b)

因此,第一个参数是常规的INTEGER类型(由x86_64 ABI定义;这包括指针)。要查找该指针参数的值,您需要查看从入口点到当前指令(即foo处)的RIP函数的反汇编。该值将传递给%rdi中的函数。

但是,%rdi中的值可能已在函数入口和转储发生的指令之间被覆盖或修改。在这种情况下,你可能需要做一些小侦探工作来倒退,找到最初传递的论据。

作为一般方法,我建议:

  • 从入口点到显示的RIP获取函数的反汇编。

  • 查看该反汇编中%rdi的使用方式。有没有修改%rdi的内容?是否存在任何函数调用(它们本身可以覆盖%rdi值)。如果没有,您的论点是00007fa6508fe910

  • 如果%rdi被修改,请查看是否已复制到另一个寄存器或保存在堆栈中。如果没有,请通过查看其反汇编来查看调用者如何生成该指针。