无法使用 GDB 进入 string.h 函数 [英] Can't step into string.h function with GDB

查看:10
本文介绍了无法使用 GDB 进入 string.h 函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 GDB 7.5 中步入 string.h 时遇到问题.这是一个简单的示例程序:

Having trouble stepping into string.h in GDB 7.5. Here's a simple example program:

源代码:

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

int main() {
    char str1[20];
    strcpy(str1, "STEP INTO ME
");
    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!
");
(gdb) step
7               printf(str_a);

此时我不应该在字符串库中吗?相反,它继续到 printf().

Shouldn't I be in the string library at this point? Instead it continues to the printf().

Scott 的建议奏效"了,但没有达到预期的效果.

Scott's suggestion "worked", but not in the expected manner.

Breakpoint 1, main () at foo.c:6
6               strcpy(str_a, "Hello, world!
");
(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.并声称没有这样的文件或目录.

I am surprised at the directory in 78... expected something like: /lib/.../cmov/libc.so.6. And the claim that there is no such file or directory.

推荐答案

使用 gcc -fno-builtin -g foo.c 和 gdb step 命令重新编译您的代码将工作.(参见 -fno-builtin 文档).否则,小的 strcpy()memcpy() 调用通常会被转换为开放编码的数据移动指令,例如在 x86-64 上:

Recompile your code with gcc -fno-builtin -g foo.c and the gdb step command will work. (See -fno-builtin documentation). Otherwise small strcpy(), memcpy() calls would often be translated into open coded data movement instructions, e.g. on 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
");
   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

您可以看到 strpcy() 调用被编译成多个 MOV 指令.

You can see the strpcy() call being compiled into multiple MOV instructions.

gcc -fno-builtin 将同一个程序编译成:

gcc -fno-builtin compiles the same program into:

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
");
   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 

你可以看到对 <strcpy@plt> 的调用.

and you can see the call to <strcpy@plt>.

假设你想进入 strcpy() 来研究它的实现,你会想要安装 libc.so 的调试信息.不幸的是,获取调试信息的方式在 Linux 发行版之间有所不同.在 Fedora 上,它就像 debuginfo-install glibc 一样简单.它在 Ubuntu 和 Debian 上需要更多步骤.此 RPM DPKG Rosetta Stone 页面包含指向 Fedora、Ubuntu 和 Debian 说明的链接(搜索 debuginfo).

Assuming you wanted to step into strcpy() to study its implementation, you'd want to have debug info for libc.so installed. Unfortunately the way to get debug info differs between Linux distros. On Fedora it's as simple as debuginfo-install glibc. It takes more steps on Ubuntu and Debian. This RPM DPKG Rosetta Stone page have links to instructions for Fedora, Ubuntu and Debian (search for debuginfo).

由于您使用的是 Ubuntu 12.10,并且实际上希望查看 strcpy() 汇编源代码:

Since you're on Ubuntu 12.10 and actually want to see the strcpy() assembly source code:

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

这篇关于无法使用 GDB 进入 string.h 函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆