【问题标题】:Debugging Linux Kernel using GDB in qemu unable to hit function or given address在 qemu 中使用 GDB 调试 Linux 内核无法命中函数或给定地址
【发布时间】:2016-08-05 21:54:43
【问题描述】:

我正在尝试在 qemu 环境中使用 GDB 逐步了解内核启动顺序。

以下是我的设置:

在一个终端中我正在运行

~/Qemu_arm/bin/qemu-system-arm -M vexpress-a9 -dtb ./arch/arm/boot/dts/vexpress-v2p-ca9.dtb -kernel ./arch/arm/boot/zImage -append "root=/dev/mmcblk0 console=ttyAMA0" -sd ../Images/RootFS.ext3 -serial stdio -s -S

在其他终端

arm-none-linux-gnueabi-gdb vmlinux
Reading symbols from vmlinux...done.
(gdb) target remote :1234
Remote debugging using :1234
0x60000000 in ?? ()

我的问题是如何为 /arch/arm/boot/compressed/* 文件中的代码设置断点。

例如,我尝试为 misc.c 中定义的 decompress_kernel 设置断点。

案例 1:

(gdb)  b decompress_kernel
Function "decompress_kernel" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 2 (decompress_kernel) pending.
(gdb) c
Continuing.

上面那个是打不到qemu正在启动的功能的。

案例 2:

(gdb) b *0x80008000
Breakpoint 1 at 0x80008000: file arch/arm/kernel/head.S, line 89.
(gdb) c
Continuing.

在这种情况下,它也无法命中,而是 qemu 正在启动。

案例 3:

(gdb) b start_kernel
Breakpoint 1 at 0x8064d8d8: file init/main.c, line 498.
(gdb) c
Continuing.

Breakpoint 1, start_kernel () at init/main.c:498
498 {
(gdb) 

在这种情况下,功能正在运行,我可以逐步调试。

注意:我已启用调试,早期 printk 并尝试过 hbreak

所以我的查询是:

  1. 为什么有些函数不能打断点?
  2. 这是 qemu 限制还是我需要启用更多功能?
  3. 我需要附加任何额外的参数吗?
  4. 如何调试早期内核启动

【问题讨论】:

  • 只是想知道函数是否被调用。能不能加个printk,确认调用了这个函数??
  • @Jeyaram 显然应该调用该函数,因为一旦内核启动它的通用函数,“解压 Linux ......完成,启动内核”。这是由 decompress_kernel() 函数完成的
  • 同意。这也是我很困惑的地方。但是如果内核图像没有被压缩会发生什么?您是否看到“Uncompressing Linux....... done, booting the kernel”消息??
  • 是的,我看到了消息,可能是串行控制台的问题,它之前可能没有初始化好,因为 putc 是平台特定的代码.. 我想不确定

标签: debugging linux-kernel gdb embedded-linux qemu


【解决方案1】:

您不能在 start_kernel 之前的任何函数上放置断点,因为您没有为它们加载符号。实际上,您使用内核的 zImage 启动 qemu,但从 vmlinux 加载符号。它们不一样:zImage 基本上是 vmlinux 压缩为数据有效负载,然后附加到存根上,存根在内存中将其解压缩,然后跳转到 start_kernel。

start_kernel 是 vmlinux 的入口点,它之前的任何函数,包括 decompress_kernel,都是存根的一部分,在 vmlinux 中不存在。

我不知道执行“arm-none-linux-gnueabi-gdb zImage”是否可以让您调试存根,我一直在真实硬件上使用 JTAG 调试器对 ARM 内核进行早期调试,从未使用过 qemu为此,对不起

【讨论】:

  • 谢谢,我会试试这个“arm-none-linux-gnueabi-gdb zImage”。只是出于好奇,我可以使用 /arm/boot/compressed/vmlinux 中的 vmlinux 代替内核本身(vmlinux),以便这个 vmlinux 拥有一切吗?
  • 顺便说一句,通过查看 System.map 地址,我试图将断点,例如断点 1 放置在 0x80008000: 文件 arch/arm/kernel/head.S 此处而不点击此地址,qemu 正在启动为什么这是所以呢?
  • 不,/arm/boot/compressed/vmlinux只是编译的中间产物。它是一个包含符号和重定位信息的精灵二进制文件,而不是原始二进制文件。你不能用它来启动系统。
  • /local/c_vhunac/vinay/Kernel_Src/Kernel/linux/arch/arm/boot/zImage":不是可执行格式:文件格式无法识别
  • 是的,当然,zImage 是一个原始二进制文件,而 gdb 需要一个 ELF……我的错。
猜你喜欢
  • 2019-09-30
  • 2015-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-09
  • 2012-07-10
  • 1970-01-01
  • 2012-02-14
相关资源
最近更新 更多