2014-10-09 55 views
7

到目前为止,通过gdb + qemu,我可以跨入Linux内核源代码。是否可以同时调试用户空间程序?例如,单步执行从用户空间到内核空间的程序,以便我可以通过发行info registers来观察qemu显示器上的寄存器更改?是否可以使用gdb和qemu同时调试linux用户空间程序和内核空间?

+0

为什么不呢?要查看任务切换,请尝试单步调试['__schedule'](http://lxr.free-electrons.com/source/kernel/sched/core.c?v=3.17#L2753),特别是正确,因为它“返回“来完成新的任务。否则,请尝试在各种系统调用中设置断点,以查看进程调用它们时会发生什么。 – 2014-10-09 06:44:11

+0

感谢Jonathon,但是当程序仍然在用户空间中运行时,我可以中断吗?实际上,我更感兴趣的是在用户空间中运行进程时观察寄存器。 – 2014-10-09 09:47:53

+0

@JeffLi您是否设法在qemu中调试用户空间程序?我试图做同样的事情,但不知道如何确定程序加载地址如何 – 2015-08-09 14:39:00

回答

3

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

+0

? – 2015-08-09 14:40:11

+0

objdump -h <程序链接文件> – Mahouk 2015-08-11 09:43:42

+0

您可以查找.text部分的VMA(链接地址)和LMA(加载地址)。这些地址为您提供您正在查找的信息 – Mahouk 2015-08-11 09:53:16

0

最小的一步setep设置

,但这里是一个fully automated QEMU + Buildroot example这presuposes你already know how to debug the kernel with QEMU + gdb和更详细的exaplanation:

readelf -h myexecutable | grep Entry 

给出:

Entry point address:    0x4003a0 

所以在GDB里面我们需要做的是:

add-symbol-file myexecutable 0x4003a0 
b main 

,然后才开始在QEMU的可执行文件:

myexecutable 

更可靠的方式做到这一点是设置myexecutable作为init过程中,如果你能做到这一点。

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

,我只能看到一个用例为这个至今:调试initDebug init on Qemu using gdb

否则,为什么不直接使用下面的更可靠的方法,例如步入一个系统调用:

我提出这一点,因为:

  • 使用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的通信开销。

    这可能让你开始:Tell gdb to skip standard files

相关问题