代码之家  ›  专栏  ›  技术社区  ›  jbcreix

使用gdb作为监视器?

  •  5
  • jbcreix  · 技术社区  · 16 年前

    GDB是否可以像传统的组装监视器那样使用?

    一旦进入例如库代码,它就会返回:

    No function contains program counter for selected frame
    

    调试程序 可以进入未知代码,但 用户界面的GDB 停止工作。

    在这方面 question 你可以找到两个建议的解决方案,但都不能让我满意。

    如果二进制库没有调试符号包呢?如果程序跳到运行时生成的代码中怎么办?

    分解代码也不是一个真正的解决方案,因为用户界面忽略了它,最重要的是,在返回到原始已知代码之前,寄存器的值不会更新。 info registers 有效,但这几乎不具有互动性。

    有什么建议吗?

    谢谢!

    1 回复  |  直到 16 年前
        1
  •  8
  •   Matthew Slattery    16 年前

    你可以用 display 命令。

    display/i $pc 将在提示前反汇编当前指令 每次打印:

    (gdb) b main
    Breakpoint 1 at 0x80483b5: file hw.c, line 5.
    (gdb) display/i $pc
    (gdb) r
    Starting program: /tmp/hw
    
    Breakpoint 1, main () at hw.c:5
    5         puts("Hello world");
    1: x/i $pc
    0x80483b5 <main+17>:    movl   $0x8048490,(%esp)
    

    现在执行一条指令(然后继续按Enter键重复):

    (gdb) si
    0x080483bc      5         puts("Hello world");
    1: x/i $pc
    0x80483bc <main+24>:    call   0x80482d4 <puts@plt>
    (gdb) 
    0x080482d4 in puts@plt ()
    1: x/i $pc
    0x80482d4 <puts@plt>:   jmp    *0x804959c
    Current language:  auto; currently asm
    (gdb) 
    0x080482da in puts@plt ()
    1: x/i $pc
    0x80482da <puts@plt+6>: push   $0x10
    (gdb) 
    0x080482df in puts@plt ()
    1: x/i $pc
    0x80482df <puts@plt+11>:        jmp    0x80482a4 <_init+48>
    

    当我们达到这一点时,它仍然有效:

    (gdb) 
    0x080482a4 in ?? ()
    1: x/i $pc
    0x80482a4 <_init+48>:   pushl  0x804958c
    (gdb) 
    0x080482aa in ?? ()
    1: x/i $pc
    0x80482aa <_init+54>:   jmp    *0x8049590
    (gdb) 
    0xb7f052d0 in _dl_runtime_resolve () from /lib/ld-linux.so.2
    1: x/i $pc
    0xb7f052d0 <_dl_runtime_resolve>:       push   %eax
    

    不止一个 显示 表达式可以同时处于活动状态(使用 undisplay <number> 移除它们)。例如,观察发生了什么 %eax 以下内容:

    (gdb) display/x $eax
    2: /x $eax = 0xbf90ab34
    (gdb) si
    0xb7f052d1 in _dl_runtime_resolve () from /lib/ld-linux.so.2
    2: /x $eax = 0xbf90ab34
    1: x/i $pc
    0xb7f052d1 <_dl_runtime_resolve+1>:     push   %ecx
    (gdb) 
    0xb7f052d2 in _dl_runtime_resolve () from /lib/ld-linux.so.2
    2: /x $eax = 0xbf90ab34
    1: x/i $pc
    0xb7f052d2 <_dl_runtime_resolve+2>:     push   %edx
    (gdb) 
    0xb7f052d3 in _dl_runtime_resolve () from /lib/ld-linux.so.2
    2: /x $eax = 0xbf90ab34
    1: x/i $pc
    0xb7f052d3 <_dl_runtime_resolve+3>:     mov    0x10(%esp),%edx
    (gdb) 
    0xb7f052d7 in _dl_runtime_resolve () from /lib/ld-linux.so.2
    2: /x $eax = 0xbf90ab34
    1: x/i $pc
    0xb7f052d7 <_dl_runtime_resolve+7>:     mov    0xc(%esp),%eax
    

    …这里的变化 %EAX公司 可以看出:

    (gdb) 
    0xb7f052db in _dl_runtime_resolve () from /lib/ld-linux.so.2
    2: /x $eax = 0xb7f0d668
    1: x/i $pc
    0xb7f052db <_dl_runtime_resolve+11>:    call   0xb7eff780 <_dl_fixup>
    (gdb) 
    
    推荐文章