【问题标题】:Finding local variables on stack using crash utility使用崩溃实用程序在堆栈上查找局部变量
【发布时间】:2014-06-08 17:36:31
【问题描述】:

我正在使用崩溃实用程序来分析 vmcore (linux) 结果,但我发现难以在函数中提取局部变量值。谷歌搜索说可以使用“信息本地人”,但是当我使用它时,它说找不到命令。

搜索了一段时间后,发现下面的链接说这种支持存在于进行自编译的崩溃购买中。 http://www.redhat.com/archives/crash-utility/2009-May/msg00003.html

vmcore dump中是否有提取局部变量的指针?

【问题讨论】:

  • 有人可以帮我解决这个问题吗?

标签: linux crash crash-dumps


【解决方案1】:

请看这篇描述 x86 栈帧布局的文章: http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/

如果您正在寻找函数参数,请注意参数 1-6 通过寄存器(rdi、rsi、..)传递,而参数 7-.. 在堆栈上传递。

所以根据定义,很容易看到参数 7-.. 的值 - 只需转储堆栈上下文: 崩溃> bt -f ...

 #6 [ffff88107fc23e08] delayed_work_timer_fn at ffffffff8108a060
    ffff88107fc23e10: ffff88107fc23e50 **ffffffff8107e329** <-- return address 
 #7 [ffff88107fc23e18] call_timer_fn at **ffffffff8107e329**
    ffff88107fc23e20: ffff88101dc6d660 ffff881020f44000 
    ffff88107fc23e30: ffff88101dc6d660 ffff88107fc23e90 
    ffff88107fc23e40: ffff881020f45020 ffffffff8108a030 
    ffff88107fc23e50: ffff88107fc23ed0 ffffffff8107e739 

查看链接。参数 7-.. 将被推送到返回地址下方的堆栈中(这里我们没有这样的参数)。

对于通过寄存器传递的参数 1-6,您必须反汇编调用函数代码并遵循它们如何获取值。大多数时候,您会看到它们从另一个寄存器中获取值。您尝试查找的是,是否在某个时候从堆栈中读取了该值。这是一个例子:

0xffffffff8107e723 <run_timer_softirq+307>:     sti    
0xffffffff8107e724 <run_timer_softirq+308>:     nopw   0x0(%rax,%rax,1)
0xffffffff8107e72a <run_timer_softirq+314>:     mov    -0x48(%rbp),%rdx <-- rdx = rbp[-0x48] <-- rdx is from the stack!!!
0xffffffff8107e72e <run_timer_softirq+318>:     mov    %r12,%rdi
0xffffffff8107e731 <run_timer_softirq+321>:     mov    %r15,%rsi
0xffffffff8107e734 <run_timer_softirq+324>:     callq  0xffffffff8107e2e0 <call_timer_fn>

static void call_timer_fn(struct timer_list *timer, void (*fn)(unsigned long),
                          unsigned long data)

所以 'call_timer_fn' 第三个参数 (rdx) 是我们在 'call_timer_fn' 堆栈中的位置 rbp[-0x48]...

这太好了……

如果不是这种情况,那么您必须继续调用跟踪和程序集 (:-(),直到您到达寄存器已知的第一个位置:

#14 [ffff88107fc23fb0] apic_timer_interrupt at ffffffff81515e33
--- <IRQ stack> ---
#15 [ffff881020f75da8] apic_timer_interrupt at ffffffff81515e33
    [exception RIP: intel_idle+193]
    RIP: ffffffff812bce31  RSP: ffff881020f75e58  RFLAGS: 00000202
    RAX: 0000000000000000  RBX: ffff88107fc2e3c0  RCX: 0000000000000000
    RDX: 0000000000007cd0  RSI: 0000000000000000  RDI: 0000000001e78df8
    RBP: ffff881020f75ea8   R8: 0000000000004183   R9: 000000000000003b
    R10: 000000a89c12c7e8  R11: 0000000000000001  R12: ffffffff81515e2e
    R13: ffff88107fc2e500  R14: 0000000000000000  R15: ffff88107fc2e3c0
    ORIG_RAX: ffffffffffffff10  CS: 0010  SS: 0018

对于局部函数变量,请参见链接。如果未优化,它们将被推入堆栈。如果可以的话,我建议禁用优化。现在您应该可以从堆栈中获取它们了。

【讨论】:

    【解决方案2】:

    info locals 是一个 gdb 命令。

    您可以创建特定进程(崩溃进程)的 coredump (crash: dump &lt;pid&gt;) 并将核心加载到 gdb(当您从内部崩溃转储核心时,它会告诉您使用生成的核心加载 gdb 的说明) .

    在gdb里面,你可以给info locals,那肯定能用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-09
      • 2019-02-16
      • 1970-01-01
      • 1970-01-01
      • 2014-04-28
      • 2020-02-24
      相关资源
      最近更新 更多