debugging 是否可以使用gdb和qemu同时调试linux用户空间程序和内核空间?

kiz8lqtg  于 2023-05-29  发布在  Linux
关注(0)|答案(3)|浏览(214)

到目前为止,使用gdb + qemu,我可以单步进入/越过linux内核源代码。是否可以同时调试用户空间程序?例如,单步执行一个从用户空间到内核空间的程序,这样我就可以通过发出info registers命令来观察qemu监视器上寄存器的变化。

t5fffqht

t5fffqht1#

最小的分步设置

Mahouk is right,但这里有一个fully automated QEMU + Buildroot example,它假定你已经知道如何使用QEMU + gdb调试内核,以及更详细的解释:

readelf -h myexecutable | grep Entry

提供:

Entry point address:               0x4003a0

所以在GDB内部我们需要做的是:

add-symbol-file myexecutable 0x4003a0
b main

然后才在QEMU中启动可执行文件:

myexecutable

更可靠的方法是将myexecutable设置为init进程(如果可以的话)。
add-symbol-file也被提到:How to load multiple symbol files in gdb

为什么你要这样做而不是gdbserver

到目前为止,我只能看到一个用例:调试initDebug init on Qemu using gdb
否则,为什么不使用以下更可靠的方法,例如:进入系统调用:

  • 启动两个远程GDB:
  • 一个qemu-system-* -s
  • 另一个gdbserver myexecutable,如以下所述:https://reverseengineering.stackexchange.com/questions/8829/cross-debugging-for-mips-elf-with-qemu-toolchain/16214#16214
  • gdbserver的GDB中,尽可能靠近系统调用,这通常意味着进入libc
  • 在QEMU的GDB上,执行例如b sys_read用于读取系统调用
  • 返回gdbserver,执行continue

我提出这一点是因为:

  • 当内核上下文切换到使用相同虚拟地址的另一个进程时,使用用户区的QEMU GDB会导致随机跳转
  • 我无法在没有gdbserver的情况下正确加载共享库:直接尝试sharedlibrary得到:
(gdb) sharedlibrary ../../staging/lib/libc.so.0
No loaded shared libraries match the pattern `../../staging/lib/libc.so.0'.

因此,由于大多数内核交互都通过stdib,因此您需要执行大量智能汇编步进来查找内核条目,这可能是不切实际的。
直到,也就是说,有人写了一个更聪明的GDB脚本,每个步骤的指令,直到上下文切换发生或直到源变得可用。我想知道这样的脚本是否会太慢,因为朴素的方法对于每条指令都有与GDB通信的开销。
这可能会让你开始:告诉gdb跳过标准文件

解析Linux内核数据结构

为了正确地进行用户态进程调试,这是我们最终必须做的:thread-aware gdb for the Linux kernel

3zwjbxry

3zwjbxry2#

我通过使用gdb命令add-symbol-file来添加用户空间程序调试信息来实现它。但是你必须知道这些程序的加载地址。因此,准确地说,您必须像往常一样通过将gdb连接到gdbserver来启动内核调试;然后,你可以添加那些程序调试信息。你也可以使用.gdbinit脚本。读取this

kkbh8khc

kkbh8khc3#

在麻省理工学院xv6操作系统实验室,我们可以使用file命令在不同的可执行文件之间切换符号表,包括xv6内核或运行在用户模式的程序。
因此,我检查它是否工作或不对Linux内核和它的用户程序。结果是它也可以工作,但我们需要保证内核和用户程序是静态链接的。
总之,您可以使用以下步骤调试用户程序:
1.当gdb和QEMU连接时,通常需要加载vmlinux符号表。按ctrl+c停止QEMU,gdb正在等待以下命令。
1.使用file [your user programs]命令切换符号表。
1.尝试在用户程序上设置断点,continue gdb并在QEMU上运行用户程序。
确保所有程序都是用-g编译的,以构建调试信息并静态链接。

相关问题