【问题标题】:Set a breakpoint into LibC with gdb使用 gdb 在 LibC 中设置断点
【发布时间】:2015-05-12 02:33:29
【问题描述】:

为什么我不能在 LibC 的导出函数中设置断点(使用 gdb)?由于是 Libc 动态链接的,它必须包含它导出的函数的符号。我不应该能够为这些函数中的任何一个设置断点吗?

我只是想这样做:

(gdb) b _IO_vfprintf@@GLIBC_2.2.5
Function "_IO_vfprintf@@GLIBC_2.2.5" not defined.

但是查看 ELF 文件中的 dynamyc-symbols 表,该符号确实存在:

 127: 0000000000049cf0 20904 FUNC    GLOBAL DEFAULT   12 _IO_vfprintf@@GLIBC_2.2.5

【问题讨论】:

    标签: linker gdb debug-symbols libc


    【解决方案1】:

    我不知道你是如何想出你正在使用的符号名称的,但这是我在我的系统 (Ubuntu 14.04.1) 上看到的:

    $ objdump --dynamic-syms /lib/x86_64-linux-gnu/libc.so.6 |grep vfprintf
    0000000000049cf0 g    DF .text  00000000000051a8  GLIBC_2.2.5 _IO_vfprintf
    00000000001097e0 g    DF .text  0000000000000111  GLIBC_2.3.4 __vfprintf_chk
    0000000000049cf0 g    DF .text  00000000000051a8  GLIBC_2.2.5 vfprintf
    

    这是一个演示程序:

       #include <stdio.h>
       #include <stdarg.h>
    
    int myprintf( const char *format, ... )
       {
       va_list ap;
       va_start( ap, format );
       int result = _IO_vfprintf( stderr, format, ap );
       va_end(ap);
       return result;
       }
    
    int main()
       {
       myprintf( "hello world! %s %s %s\n", "abc", "def", "ghi" );
       myprintf( "goodbye world! %d %d\n", 123, 456 );
       return 0;
       }
    

    我发现如果我首先运行到main(),它的抱怨更少,然后只用b _IO_vfprintf设置一个断点。

    $ make CFLAGS="-Wall -Werror -g" test && ./test
    
    $ objdump --disassemble test |grep vfprintf ## verify call isn't inlined
    0000000000400480 <_IO_vfprintf@plt>:
      40061e:   e8 5d fe ff ff          callq  400480 <_IO_vfprintf@plt>
    
    $ gdb --quiet ./test
    Reading symbols from ./test...done.
    
    (gdb) b main
    Breakpoint 1 at 0x400635: file test.c, line 16.
    
    (gdb) run
    Starting program: .../test 
    
    Breakpoint 1, main () at test.c:16
    16     myprintf( "hello world! %s %s %s\n", "abc", "def", "ghi" );
    
    (gdb) b _IO_vfprintf
    Breakpoint 2 at 0x7ffff7a5ecf4
    
    (gdb) cont
    Continuing.
    
    Breakpoint 2, 0x00007ffff7a5ecf4 in vfprintf () from /lib/x86_64-linux-gnu/libc.so.6
    

    所以是的,它有效...


    更上一层楼——您可以通过应用以下命令逐步浏览 libc 源代码...

    $ sudo apt-get install libc6-dbg ## get the debug symbols
    $ apt-get source libc-dev-bin ## download the source (on Ubuntu or similar)
    $ gdb --quiet --directory ./eglibc-2.19/stdio-common ./test
    

    相关说明here.

    【讨论】:

    • 你是对的。如果我启动程序,那么我可以使用它的符号作为断点值进入 Libc。我认为那是因为当我运行 gdb 时还没有加载这些库。它们仅在我运行程序时加载。谢谢。
    猜你喜欢
    • 2021-04-01
    • 2014-09-22
    • 2015-09-22
    • 1970-01-01
    • 1970-01-01
    • 2018-12-15
    • 2012-03-29
    • 2015-10-05
    相关资源
    最近更新 更多