2015-05-12 6 views
4

Почему я не могу установить точку останова (используя gdb) в экспортируемой функции в LibC? Будучи динамически связанным с Libc, он должен содержать символы функций, которые он экспортирует. Разве я не могу установить точку останова для любой из этих функций?Установить точку останова в LibC с помощью gdb

Я просто пытался сделать:

(gdb) b [email protected]@GLIBC_2.2.5 
Function "[email protected]@GLIBC_2.2.5" not defined. 

Но, глядя на таблицу dynamyc-символов в ELF файл символ существует:

127: 0000000000049cf0 20904 FUNC GLOBAL DEFAULT 12 [email protected]@GLIBC_2.2.5 

ответ

2

Я не знаю, как вы пришли с именем символа, который вы используете, но вот что я вижу в моей системе (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 <[email protected]>: 
    40061e: e8 5d fe ff ff   callq 400480 <[email protected]> 

$ 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.

+0

Вы правы. Если я запустил программу, я могу перейти в Libc, используя ее символы в качестве значений точки останова. Я думаю, это потому, что библиотеки не загружаются, когда я еще запускал gdb. Они загружаются только при запуске программы. Благодарю. – badnack