No puede entrar en la función string.h con GDB

Tiene problemas para entrar en string.h en GDB 7.5. Aquí hay un progtwig de ejemplo simple:

Código fuente:

 #include  #include  int main() { char str1[20]; strcpy(str1, "STEP INTO ME\n"); printf(str1); } 

Comstackdo: ~$ gcc -g foo.c

Invocado: ~$ gdb -q ./a.out

GDB:

 (gdb) break 5 Breakpoint 1 at 0x8048471: file foo.c, line 6. (gdb) break strcpy Function "strcpy" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 2 (strcpy) pending. (gdb) run Starting program: /home/user/a.out Breakpoint 1, main () at foo.c:6 6 strcpy(str_a, "Hello, world!\n"); (gdb) step 7 printf(str_a); 

¿No debería estar en la biblioteca de cuerdas en este punto? En cambio, continúa al printf ().


EDITAR:

La sugerencia de Scott “funcionó”, pero no de la manera esperada.

 Breakpoint 1, main () at foo.c:6 6 strcpy(str_a, "Hello, world!\n"); (gdb) ir $eip eip 0x80484a1 0x80484a1  (gdb) step Breakpoint 2, __strcpy_ssse3 () at ../sysdeps/i386/i686/multiarch/strcpy-ssse3.S:78 78 ../sysdeps/i386/i686/multiarch/strcpy-ssse3.S: No such file or directory. (gdb) ir $eip eip 0xb7e9c820 0xb7e9c820  

Me sorprende el directorio en 78 … esperaba algo como: /lib/.../cmov/libc.so.6 . Y la afirmación de que no hay tal archivo o directorio.

Recompile su código con gcc -fno-builtin -g foo.c y el comando gdb step funcionará. (Consulte la documentación de -fno-built-in ). De lo contrario, las llamadas pequeñas strcpy() , memcpy() a menudo se traducirían en instrucciones de movimiento de datos con código abierto, por ejemplo, en x86-64:

 4 int main() { 0x000000000040052c <+0>: push %rbp 0x000000000040052d <+1>: mov %rsp,%rbp 0x0000000000400530 <+4>: sub $0x20,%rsp 5 char str1[20]; 6 strcpy(str1, "STEP INTO ME\n"); 0x0000000000400534 <+8>: lea -0x20(%rbp),%rax 0x0000000000400538 <+12>: movl $0x50455453,(%rax) 0x000000000040053e <+18>: movl $0x544e4920,0x4(%rax) 0x0000000000400545 <+25>: movl $0x454d204f,0x8(%rax) 0x000000000040054c <+32>: movw $0xa,0xc(%rax) 7 printf(str1); 0x0000000000400552 <+38>: lea -0x20(%rbp),%rax 0x0000000000400556 <+42>: mov %rax,%rdi 0x0000000000400559 <+45>: mov $0x0,%eax 0x000000000040055e <+50>: callq 0x400410  8 } 0x0000000000400563 <+55>: leaveq 0x0000000000400564 <+56>: retq 

Puede ver la llamada strpcy() comstackda en varias instrucciones MOV .

gcc -fno-builtin comstack el mismo progtwig en:

 4 int main() { 0x000000000040057c <+0>: push %rbp 0x000000000040057d <+1>: mov %rsp,%rbp 0x0000000000400580 <+4>: sub $0x20,%rsp 5 char str1[20]; 6 strcpy(str1, "STEP INTO ME\n"); 0x0000000000400584 <+8>: lea -0x20(%rbp),%rax 0x0000000000400588 <+12>: mov $0x400660,%esi 0x000000000040058d <+17>: mov %rax,%rdi 0x0000000000400590 <+20>: callq 0x400450  7 printf(str1); 0x0000000000400595 <+25>: lea -0x20(%rbp),%rax 0x0000000000400599 <+29>: mov %rax,%rdi 0x000000000040059c <+32>: mov $0x0,%eax 0x00000000004005a1 <+37>: callq 0x400460  8 } 0x00000000004005a6 <+42>: leaveq 0x00000000004005a7 <+43>: retq 

y puede ver la llamada a .

Asumiendo que quería entrar en strcpy() para estudiar su implementación, le gustaría tener información de depuración para libc.so instalado. Lamentablemente, la forma de obtener información de depuración difiere entre las distribuciones de Linux. En Fedora es tan simple como debuginfo-install glibc . Se necesitan más pasos en Ubuntu y Debian. Esta página de RPM DPKG Rosetta Stone tiene enlaces a las instrucciones para Fedora, Ubuntu y Debian (búsqueda de debuginfo ).

Ya que está en Ubuntu 12.10 y realmente quiere ver el código fuente del ensamblado strcpy() :

 $ sudo apt-get install libc6-dbg $ sudo apt-get source libc6-dev $ gdb ./a.out (gdb) directory eglibc-2.15/sysdeps Source directories searched: /home/scottt/eglibc-2.15/sysdeps:$cdir:$cwd (gdb) break strcpy Breakpoint 1 at 0x400450 (gdb) run Starting program: /home/scottt/a.out Breakpoint 1, __strcpy_sse2 () at ../sysdeps/x86_64/multiarch/../strcpy.S:32 32 movq %rsi, %rcx /* Source register. */ 

Ha intentado establecer un punto de interrupción para una función definida en la biblioteca de cadenas que generalmente forma parte de la standard C library - libc.so

Y como gdb te informa:

 (gdb) break strcpy Function "strcpy" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 2 (strcpy) pending. 

la biblioteca no está cargada todavía

Pero el verdadero problema es que, incluso cuando la biblioteca está cargada, si la biblioteca, es decir, libc.so no tiene símbolos de depuración, no podrá pasar el código dentro de la biblioteca usando gdb .

Puede habilitar el modo detallado para ver qué símbolos, gdb puede cargar:

 (gdb) b main Breakpoint 1 at 0x400914: file test.cpp, line 7. (gdb) set verbose on (gdb) run Starting program: /home/agururaghave/.scratch/gdb-test/test Reading symbols from /lib64/ld-linux-x86-64.so.2...(no debugging symbols found)...done. Loaded symbols for /lib64/ld-linux-x86-64.so.2 Reading symbols from system-supplied DSO at 0x7ffff7ffb000...(no debugging symbols found)...done. Reading symbols from /usr/lib64/libstdc++.so.6...(no debugging symbols found)...done. Registering libstdc++-v6 pretty-printer for /usr/lib64/libstdc++.so.6 ... Loaded symbols for /usr/lib64/libstdc++.so.6 Reading symbols from /lib64/libm.so.6...(no debugging symbols found)...done. Loaded symbols for /lib64/libm.so.6 Reading symbols from /lib64/libgcc_s.so.1...(no debugging symbols found)...done. Loaded symbols for /lib64/libgcc_s.so.1 Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done. Loaded symbols for /lib64/libc.so.6 Breakpoint 1, main () at test.cpp:7 7 bool result = myObj1 < myObj2; 

Esta línea, por ejemplo, le dice si fue capaz de obtener los símbolos de libc.so:

 Reading symbols from /lib64/libc.so.6...(no debugging symbols found)...done. 

A continuación, puede averiguar dónde se recogen los símbolos de depuración utilizando show debug-file-directory :

 (gdb) show debug-file-directory The directory where separate debug symbols are searched for is "/usr/lib/debug". 

Como puede ver /usr/lib/debug aquí no contiene el .so completo con símbolos de depuración. En su lugar, solo tiene la información de depuración sin secciones .text o .data de la libc.so real que el progtwig usa para la ejecución.

La solución para instalar la información de depuración para las bibliotecas sería específica de la distribución.

Creo que el paquete se llama libc6-dbg en las distribuciones basadas en Debian. En mi máquina openSUSE, parece que se llama glibc-debuginfo

Por cierto, +1 en la sugerencia de -fno-builtin de usar -fno-builtin para que gcc no use sus métodos incorporados para funciones como strcpy y otras estándares definidas como parte del estándar C.

Probablemente no tenga ningún símbolo para su biblioteca C. Pruebe stepi , pero prepárese para ver solo las instrucciones de ensamblaje.