2013-03-09 4 views
10

Ошибка при входе в string.h в GDB 7.5. Вот простой пример программы:Невозможно перейти в функцию string.h с помощью GDB

Исходный код:

#include <stdio.h> 
#include <string.h> 

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

Составитель:~$ gcc -g foo.c

Вызванный:~$ 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); 

Должен ли я быть в библиотеке строк на этом этапе? Вместо этого он продолжает printf().


EDIT:

предложение Скотта "работал", но не в ожидаемом порядке.

Breakpoint 1, main() at foo.c:6 
6    strcpy(str_a, "Hello, world!\n"); 
(gdb) i r $eip 
eip   0x80484a1  0x80484a1 <main+21> 
(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) i r $eip 
eip   0xb7e9c820  0xb7e9c820 <__strcpy_ssse3> 

Я удивлен каталог в 78 ... ожидал что-то вроде: /lib/.../cmov/libc.so.6. И утверждение, что нет такого файла или каталога.

+0

@skirkpatrick: Это не так, по крайней мере, на большинстве систем (OS X, Debian, Ubuntu, Fedora. ..). Общие библиотеки * * скомпилированы с помощью отладочных символов. Реальный вопрос заключается в том, установлены ли эти символы. –

+0

@ DietrichEpp: После быстрого поиска, похоже, что вы правы. Извините за дезинформацию; Я удалю свой комментарий. – skirkpatrick

+0

Отладочные символы не являются частью .so, которые находятся в вашем LD_LIBRARY_PATH. Вместо этого они находятся в каталоге, который ищет gdb, например '/ usr/lib/debug'. Эту информацию можно получить, запустив 'show debug-file-directory' в' gdb'. Эти файлы содержат только отладочную информацию без каких-либо разделов '.text' или' .data' '.so'. И да, вам нужно установить их отдельно. – Tuxdude

ответ

16

Перекомпилируйте код с помощью gcc -fno-builtin -g foo.c и команда gdb step будет работать. (См. -fno-builtin documentation). В противном случае небольшие вызовы strcpy(), memcpy() часто переводятся в инструкции по перемещению открытых кодированных данных, например. на 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 <[email protected]> 

8 } 
    0x0000000000400563 <+55>: leaveq 
    0x0000000000400564 <+56>: retq 

Вы можете увидеть strpcy() вызов составляется на несколько MOV инструкции.

gcc -fno-builtin компилирует ту же программу в:

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 <[email protected]> 

7  printf(str1); 
    0x0000000000400595 <+25>: lea -0x20(%rbp),%rax 
    0x0000000000400599 <+29>: mov %rax,%rdi 
    0x000000000040059c <+32>: mov $0x0,%eax 
    0x00000000004005a1 <+37>: callq 0x400460 <[email protected]> 

8 } 
    0x00000000004005a6 <+42>: leaveq 
    0x00000000004005a7 <+43>: retq 

и вы можете увидеть вызов <[email protected]>.

Предполагая, что вы хотите перейти на strcpy(), чтобы изучить его реализацию, вы хотите получить информацию об отладке для установленного libc.so. К сожалению, способ получить информацию об отладке отличается от дистрибутивов Linux. На Fedora это так же просто, как debuginfo-install glibc. Для Ubuntu и Debian требуется больше шагов. На этой странице RPM DPKG Rosetta Stone есть ссылки на инструкции для Fedora, Ubuntu и Debian (поиск по debuginfo).

Поскольку вы на Ubuntu 12.10 и на самом деле хотят видеть 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. */ 
+0

Предполагается, что 't.c' должен представлять' foo.c' (в данном случае) или является файлом, с которым я должен связываться? – d0rmLife

+0

Я пробовал это. Шаги, но он переходит в неожиданный каталог и говорит: «Нет такого файла или каталога *. Я опубликую результаты в своем вопросе ... форматирование в комментариях будет жестоким. – d0rmLife

+0

@ d0rmLife: похоже, что strcpy реализована в сборке в glibc – teppic

0

У вас, вероятно, нет символов для вашей библиотеки C. Попробуйте stepi, но будьте готовы видеть только инструкции по сборке.

+0

'stepi' также не входит в библиотеку. Заглядывая в другую причину ... – d0rmLife

+0

@ d0rmLife, ты уверен? Как вы проверили? –

+0

Запустив 'GDB' и используя' stepi'. Нет, я думаю, я не уверен, но это не похоже. По крайней мере, не обычным способом ... – d0rmLife

3

Вы попытались установить контрольную точку для функции, определенной в библиотеке строки обычно является частью standard C library - libc.so

И как gdb сообщает вам:

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

Breakpoint 2 (strcpy) pending. 

библиотека еще не загружена.

Но реальная проблема заключается в том, что даже если библиотека загружена, если библиотека i.e. libc.so не содержит в ней отладочных символов, вы не сможете пройти через код в библиотеке, используя gdb.

Вы можете включить подробный режим, чтобы увидеть, какие символы, gdb умеет загружать:

(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; 

Эта линия, например, говорит вам, был ли он в состоянии получить символы для libc.so:

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

Вы могли бы выяснить, где символы отладки подбираются с помощью show debug-file-directory:

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

Как вы видите, /usr/lib/debug здесь не содержит полного .so с отладочными символами. Вместо этого он имеет только информацию об отладке без каких-либо .text или .data разделов фактического libc.so, которые программа использует для выполнения.

Решение установить информацию об отладке для библиотек будет специфичным для дистрибутива.

Я думаю, что пакет называется libc6-dbg на дистрибутивах на основе debian. На моей машине OpenSUSE, это, кажется, называется glibc-debuginfo

BTW, +1 по предложению scottt «s использования -fno-builtin так, что GCC не использует свои встроенные методы для функций, таких как strcpy и других стандартных определенных в рамках C.

+0

Не проблема ли libc.so для отладки информации здесь. Поскольку программа динамически связана, если существует вызов strcpy(), который проходит через PLT, gdb поймает его. Проблема здесь в том, что опция gcc '-fno-buitin' не была передана, а вызов strcpy() в источнике был переведен в инструкции хранилища. – scottt

+0

Любая идея, что пакет может быть вызван для Ubuntu 12? – d0rmLife

+0

Попробуйте 'sudo apt-get install libc6-dbg' – Tuxdude

Смежные вопросы