如何使用-O0编译Linux内核以进行更详细的调试?

问题描述 投票:0回答:1

我正在破解 Linux 内核 v5.15,并尝试使用

gdb
逐行调试它。我已经通过
make menuconfig
打开了矮人调试信息。不过,似乎还是会跳过一些行。我发现默认的编译优化是-O2。所以我改变了 Makefile,如下所示:

ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE
KBUILD_CFLAGS += -O2 # here change to -O0
else ifdef CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE_O3
KBUILD_CFLAGS += -O3
else ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
KBUILD_CFLAGS += -Os
endif

然后我再次编译:

make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -j$(nproc)

但它给出了:

  CALL    scripts/checksyscalls.sh
  CALL    scripts/atomic/check-atomics.sh
  CC      init/main.o
In file included from ././include/linux/compiler_types.h:85,
                 from <command-line>:
./arch/riscv/include/asm/jump_label.h: In function ‘want_init_on_alloc’:
./include/linux/compiler-gcc.h:88:38: warning: ‘asm’ operand 0 probably does not match constraints
   88 | #define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
      |                                      ^~~
./arch/riscv/include/asm/jump_label.h:20:9: note: in expansion of macro ‘asm_volatile_goto’
   20 |         asm_volatile_goto(
      |         ^~~~~~~~~~~~~~~~~
./include/linux/compiler-gcc.h:88:38: error: impossible constraint in ‘asm’
   88 | #define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
      |                                      ^~~
./arch/riscv/include/asm/jump_label.h:20:9: note: in expansion of macro ‘asm_volatile_goto’
   20 |         asm_volatile_goto(
      |         ^~~~~~~~~~~~~~~~~
./arch/riscv/include/asm/jump_label.h: In function ‘want_init_on_free’:
./include/linux/compiler-gcc.h:88:38: warning: ‘asm’ operand 0 probably does not match constraints
   88 | #define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0)
      |                                      ^~~
./arch/riscv/include/asm/jump_label.h:20:9: note: in expansion of macro ‘asm_volatile_goto’
   20 |         asm_volatile_goto(
      |         ^~~~~~~~~~~~~~~~~
make[1]: *** [scripts/Makefile.build:277: init/main.o] Error 1
make: *** [Makefile:1868: init] Error 2

如果优化参数确实无法更改,有没有办法更细粒度地调试内核?

gcc makefile linux-kernel gdb dwarf
1个回答
0
投票

不过,似乎还是会跳过一些行。我发现默认的编译优化是-O2。

这是正常的,内核代码不是为了在关闭优化的情况下编译而编写的。事实上,它严重依赖于编译器优化,并且从我自己的经验我知道它不会用

-O0
进行编译。在某些情况下,它可能会与
-O1
一起编译,但我不认为这是一个保证。

您可以尝试使用

-O1
,这会让您有所收获,但我建议保留默认值
-O2
。当然,在您的配置中启用调试信息的生成(在
make menuconfig
中,在“内核黑客”->“编译时检查和编译器选项”下)。还有
CONFIG_READABLE_ASM
,如果启用,将尝试生成更多人类可读的汇编代码。

有没有更细粒度的内核调试方法?

其实不然。做到这一点的唯一真正方法是足够精通汇编,以了解正在发生的事情、优化的内容和未优化的内容。即使优化级别较低,许多内核代码也使用静态和内联函数,这些函数将被编译器简化和内联。调试此类代码时,您会看到 GDB 不断地跳来跳去。你对此无能为力。

将 GDB 与

layout split
一起使用是同时显示代码和汇编的最佳方法。请查看 这个 GDB 文档页面这个其他问题 以获取更多见解。

如果您想以这种方式精通调试,请首先研究您正在处理的架构上的调用约定是什么以及用于调用、返回和分支的指令。这将使您一目了然地了解汇编的哪些部分与 C 代码相匹配。除此之外,这只是练习的问题。

© www.soinside.com 2019 - 2024. All rights reserved.