无法进入系统调用源代码

7

我已用-g选项编译了我的freebsd libc源代码,现在我可以进入libc函数。

但是,我遇到了无法进入系统调用代码的问题。我已使用-g选项编译了freebsd内核源代码。在设置断点时,GDB会提示关于.S文件的断点信息。在触发断点后,GDB无法进入系统调用源代码。

此外,我还尝试了:gdb$catch syscall open,但这也没有起作用。

请问你能给出什么建议吗?

谢谢。


1
在Linux上进行调试是通过ptrace(2)系统调用实现的; ptrace仅能检查和停止在用户空间运行的进程。我预计FreeBSD的进程调试机制类似,并且仅设计用于在用户空间工作的进程:因为操作系统内核将快速获取和释放锁以及响应中断,所以从用户空间设计允许全功能调试似乎非常不可能。 - sarnold
1
嗨,Sarnold,感谢您的评论。如果用户空间调试不可行,那么kdb/kgdb可以起到作用吗? - Sandeep Singh
我已经多年没有研究kdb/kgdb了,也许现在情况已经发生了很大的变化。:) 但是也许关于堆栈转储的这条消息会是一个不错的起点? - sarnold
2个回答

9

您似乎对UNIX系统的工作原理缺乏基本的了解。

想象一下,假设您能够进入实现系统调用的内核函数,比如说sys_open。那么现在您正在调试器中查看sys_open的内核源代码。问题是:此时内核正在运行还是停止。由于您希望执行像next这样的操作,让我们假设内核已经停止。

那么现在您按下n键,会发生什么?

通常情况下,内核会响应键盘引发的中断,确定按下了哪个键,并将该键发送到正确的进程(在控制键盘的终端上阻塞在read(2)中的进程)。

但是,您的内核已经停止,所以您无法进行按键。

结论:通过在同一台机器上运行的调试器来调试内核是不可能的。

事实上,当人们调试内核时,通常是在另一台机器上运行调试器(这称为远程调试)。

如果您真的想进入内核,最简单的方法是使用UML

在您玩了UML并了解了用户空间/内核接口的工作原理和交互方式之后,您可以尝试kgdb,尽管设置通常会更加复杂。您实际上不必为此拥有单独的机器,您可以使用VMWare、VirtualPC或VirtualBox。


1
你的“通过在同一台机器上运行的调试器调试内核是不可能的”结论仅适用于Linux上的kgdb。UML也是Linux特定的解决方案。虽然有一个针对FreeBSD的kgdb端口,但FreeBSD内核可以像Solaris使用kmdb一样本地调试。 - jlliagre
2
你关于内核调试器无法工作的解释是有缺陷的。内核不是一个单线程程序,甚至也不是多线程程序。内核是在特权上下文中执行的代码。许多内核线程可以同时运行此代码,因此影响其中一个线程执行的指令的断点没有充分的理由突然“停止内核”,即停止其他所有内核线程。 - jlliagre

3
如Employed Russian所述,由于gdb位于用户空间,无法检查运行在内核中的任何内容。
但是,没有什么可以阻止在内核本身中实现调试器。在这种情况下,可以从本地调试会话(控制台)设置断点并逐步运行内核代码。在FreeBSD中,这样的调试器可用作ddb
一些限制将是您的gdb和ddb会话之间缺乏连接,并且我不确定在FreeBSD / ddb下是否提供源级别调试(-g)用于内核代码。
从用户空间“调试”内核的另一种更少侵入性的方法是使用dtrace

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接