Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set a breakpoint into LibC with gdb

Why I cannot set a breakpoint (using gdb) in an exported function within LibC? As being Libc dynamically linked, it must contains the symbols of the functions it exports. Shouldn't I be able to set a breakpoint to any of these functions?

I merely tried to do:

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

But looking at the dynamyc-symbols table in the ELF file the symbol does exist:

 127: 0000000000049cf0 20904 FUNC    GLOBAL DEFAULT   12 _IO_vfprintf@@GLIBC_2.2.5
like image 520
badnack Avatar asked May 12 '15 02:05

badnack


1 Answers

I don't know how you came up with the symbol name that you are using, but here's what I see on my system (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

Here's a demonstration program:

   #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;
   }

I found that it complains less if I first run to main(), then set a breakpoint with just 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

So yes, it works...


Taking it to the next level -- you can step through the libc source by applying the following commands...

$ 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

Related notes here.

like image 116
Brent Bradburn Avatar answered Nov 15 '22 12:11

Brent Bradburn