在我的一些系统上,当我调试非常简单的代码时,GDB的行为与我预期的不同。在某些系统上,当我进入'步骤时,gdb"掩盖"标准库调用;在其他系统上,' step'下载到每个库调用的机器语言。
首先,我从GDB习惯的行为示例:
$ gdb ./testapp
GNU gdb (GDB) CentOS (7.0.1-45.el5.centos)
(...)
(gdb) break main
Breakpoint 1 at 0x80483b6: file testapp.c, line 6.
(gdb) run
Starting program: ./testapp
Breakpoint 1, main () at testapp.c:6
6 char str[] = {"Test string"};
(gdb) step
8 printf("String: %s\n", str );
(gdb)
String: Test string
9 printf("Len: %zu\n", strlen( str ));
(gdb)
Len: 11
10 return 0;
(gdb)
这是GDB逐步进入printf()到机器语言步骤的一个例子。
$ gdb ./testapp
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-92.el6)
(...)
(gdb) break main
Breakpoint 1 at 0x40050c: file testapp.c, line 6.
(gdb) run
Starting program: ./testapp
Breakpoint 1, main () at testapp.c:6
6 char str[] = {"Test string"};
(gdb) step
8 printf("String: %s\n", str );
(gdb)
__printf (format=0x400668 "String: %s\n") at printf.c:30
30 {
(gdb)
34 va_start (arg, format);
(gdb)
35 done = vfprintf (stdout, format, arg);
(gdb)
_IO_vfprintf_internal (s=0x383958f040, format=0x400668 "String: %s\n", ap=0x7fffffffe330) at vfprintf.c:236
236 int save_errno = errno;
(gdb)
201 {
(gdb)
236 int save_errno = errno;
(gdb)
1283 ORIENT;
(gdb)
1287 ARGCHECK (s, format);
(gdb)
1298 if (UNBUFFERED_P (s))
(gdb)
1309 __va_copy (ap_save, ap);
(gdb)
1320 f = lead_str_end = __find_specmb ((const UCHAR_T *) format);
(gdb)
__find_specmb (s=0x383958f040, format=0x400668 "String: %s\n", ap=0x7fffffffe330) at printf-parse.h:109
109 return (const unsigned char *) __strchrnul ((const char *) format, '%');
(gdb)
_IO_vfprintf_internal (s=0x383958f040, format=0x400668 "String: %s\n", ap=0x7fffffffe330) at vfprintf.c:1309
1309 __va_copy (ap_save, ap);
(gdb)
1320 f = lead_str_end = __find_specmb ((const UCHAR_T *) format);
(gdb)
__find_specmb (s=0x383958f040, format=0x400668 "String: %s\n", ap=0x7fffffffe330) at printf-parse.h:109
109 return (const unsigned char *) __strchrnul ((const char *) format, '%');
(gdb)
strchrnul () at ../sysdeps/x86_64/strchrnul.S:27
27 movd %esi, %xmm1
(gdb)
28 movq %rdi, %rcx
(gdb)
29 punpcklbw %xmm1, %xmm1
(gdb)
以下是" testapp.c"的来源:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(){
char str[] = {"Test string"};
printf("String: %s\n", str );
printf("Len: %zu\n", strlen( str ));
return 0;
}
该程序在两种环境中编译如下:
cc -g -o testapp testapp.c
这是我关于Stack Overflow的第一个问题!任何帮助将不胜感激!谢谢!
答案 0 :(得分:3)
你没有看到&#34;机器语言&#34;。你看到了图书馆的源代码。
在某些机器上,库显然安装了调试信息和源代码。做一个&#34;步骤&#34;在那台机器上将进入程序。在另一台机器上,库显然没有安装调试信息,所以&#34;步骤&#34;命令步骤。
注意:&#34;步骤&#34;在所有情况下,命令都应该进入库。如果没有源代码,您应该看到(真实的)机器语言。似乎gdb没有这样做(VS确实如此)。
答案 1 :(得分:1)
约翰对原始帖子的评论将其钉住了。
我发现正在进入库的机器安装了两个调试包:glibc-debuginfo
和glibc-debuginfo-common
。
使用yum remove glibc-debuginfo glibc-debuginfo-common
删除它们之后,GDB现在按照我预期的方式工作!
非常感谢,约翰!
答案 2 :(得分:0)
您似乎对gdb
的“步骤”和“下一步”命令有误解。
'step'尝试执行到执行路径中的下一行代码(其全名是'step into'。
'next'尝试执行当前行之后的代码行。 (它不会停留在被调用的函数中。