使用最大的调试符号和最低的优化进行编译仍会跳过部分代码

Joh*_*ord 3 c debugging gcc gdb

重现步骤:

  • 克隆emacs存储库
    • git clone https://github.com/emacs-mirror/emacs.git
  • 运行样板程序以准备构建/创建Makefile
    • i@user:~/emacs$ ./autogen.sh; ./configure
  • 导航到目录lib-src/以构建etags二进制文件
    • cd lib-src/
  • etags通过Makfilelib-src/目录中进行编辑,确保使用最多的调试符号编译二进制文件,并且进行尽可能少的优化

    • CC=gcc
    • CFLAGS=-fno-eliminate-unused-debug-types -g3 -O0
    • CPPFLAGS =
    • LDFLAGS =
  • 建立etags二进制目标

    • make tags
  • 通过gdb使用如下所示的参数进行简单的测试,测试出调试时不会跳过任何代码:etags --help
gdb etags
(gdb) b main
Breakpoint 1 at 0x37ca: file etags.c, line 1071.
(gdb) r
Starting program: /home/i/emacs/lib-src/etags 
Breakpoint 1, main (argc=1, argv=0x7fffffffdfb8) at etags.c:1071
1071    {
(gdb) n
1078      bool help_asked = false;
(gdb) n
1083      progname = argv[0];
(gdb) n
1084      nincluded_files = 0;
(gdb) n
1085      included_files = xnew (argc, char *);
(gdb)
Run Code Online (Sandbox Code Playgroud)

如您所见,gdb跳过了1072-1077行,它对应于以下代码:

gdb etags
(gdb) b main
Breakpoint 1 at 0x37ca: file etags.c, line 1071.
(gdb) r
Starting program: /home/i/emacs/lib-src/etags 
Breakpoint 1, main (argc=1, argv=0x7fffffffdfb8) at etags.c:1071
1071    {
(gdb) n
1078      bool help_asked = false;
(gdb) n
1083      progname = argv[0];
(gdb) n
1084      nincluded_files = 0;
(gdb) n
1085      included_files = xnew (argc, char *);
(gdb)
Run Code Online (Sandbox Code Playgroud)

我想念什么吗?我是否应该添加一个标志,以确保在生成调试符号时不会跳过任何代码行?

Emp*_*ian 6

我想念什么吗?

是的:1072-1077行是声明,并且编译器不会为它们发出任何可执行代码。

next工作方式是:一次单步执行程序一条指令,直到当前行与next执行开始时的当前行不匹配(也就是说,如果您当前在X行上停止,则单步执行直到当前行!= X ),然后停止。

由于没有任何指令可以在1072和1077之间的任何行上停下来,因此单步执行将立即使您进入1078行。

这是按设计工作。