无法进入string.hGDB 7.5.这是一个简单的示例程序:
源代码:
#include <stdio.h>
#include <string.h>
int main() {
char str1[20];
strcpy(str1, "STEP INTO ME\n");
printf(str1);
}
Run Code Online (Sandbox Code Playgroud)
编译: ~$ 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);
Run Code Online (Sandbox Code Playgroud)
我不应该在字符串库中吗?相反,它继续printf().
编辑:
斯科特的建议"有效",但不是以预期的方式.
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>
Run Code Online (Sandbox Code Playgroud)
我很惊讶78... ...的预期目录:/lib/.../cmov/libc.so.6.声称没有这样的文件或目录.
sco*_*ttt 16
用你的代码重新编译gcc -fno-builtin -g foo.c,gdb step命令就可以了.(参见-fno-builtin文档).否则很小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 <printf@plt>
8 }
0x0000000000400563 <+55>: leaveq
0x0000000000400564 <+56>: retq
Run Code Online (Sandbox Code Playgroud)
您可以看到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 <strcpy@plt>
7 printf(str1);
0x0000000000400595 <+25>: lea -0x20(%rbp),%rax
0x0000000000400599 <+29>: mov %rax,%rdi
0x000000000040059c <+32>: mov $0x0,%eax
0x00000000004005a1 <+37>: callq 0x400460 <printf@plt>
8 }
0x00000000004005a6 <+42>: leaveq
0x00000000004005a7 <+43>: retq
Run Code Online (Sandbox Code Playgroud)
你可以看到电话<strcpy@plt>.
假设你想进入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. */
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6683 次 |
| 最近记录: |