使用最大调试符号和最低优化进行编译仍然会跳过代码片段

标签 c debugging gcc gdb

重现步骤:

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

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

    • 制作标签
  • 通过在 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)

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

// ...
// ...
// ...
int                             // Line 1069
main (int argc, char **argv)    // Line 1070
{                               // Line 1071
  int i;                        // Line 1072
  unsigned int nincluded_files; // Line 1073
  char **included_files;        // Line 1074
  argument *argbuffer;          // Line 1075
  int current_arg, file_count;  // Line 1076
  linebuffer filename_lb;       // Line 1077
  bool help_asked = false;      // Line 1078
  ptrdiff_t len;                // Line 1079
  char *optstring;              // Line 1080
  int opt;                      // Line 1081
// ...
// ...
// ...

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

最佳答案

Am I missing something?

是的:第 1072-1077 行是声明,编译器不会为它们生成任何可执行代码。

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

由于没有指令停止对应于 1072 和 1077 之间的任何行,单步执行一次立即到达 1078 行。

这是按设计工作的。

关于使用最大调试符号和最低优化进行编译仍然会跳过代码片段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57455948/

相关文章:

c++ - 意外的位移结果

angularjs - 如何在Chrome浏览器中调试AngularJS

c++ - 将编译版本复制到另一台主机时出现 GCC 编译错误

c - 如何从结构定义生成函数?

C 预处理器 : line continuation: why exactly comment is not allowed after backslash character ('\' )?

c - 是否可以在 GDB 调试器中使用 "jump"/"skip"?

debugging - 除了测试现有测试的覆盖率之外,是否还有软件故障注入(inject)的用途?

gcc - 如何将centos 6.9中的gcc 4.7.2升级到gcc 4.8

c - 如何避免使用gcc在c中包装输入数据?

c - 宏计数参数