控制器和目标之间的通信通过重复调用 ptrace 进行,在两者之间传递一个固定大小的小内存块(每次调用需要两次上下文切换);当访问大量目标内存时,这是非常低效的,因为这只能在字大小的块中完成(每个字都有一个 ptrace 调用)。 [7]因此,Unix 第 8 版引入了 procfs,它允许允许进程直接访问另一个进程的内存 - 随后是 4.4BSD,使用 /proc 进行调试器支持被 Solaris、BSD 和 AIX 继承,并且大部分被复制通过Linux
更快的内存访问是否是调试器唯一关心的/proc
允许但不可能的事情ptrace
?例如,是否可以通过 获得有关正在运行的程序的更多与调试器相关的信息/proc
?与调试器相关的其他操作程序的方法怎么样?通常会/proc
比ptrace
读取大内存块更有效,或者读取大内存块是唯一明显性能较低的情况吗?
答案1
如果调试器喜欢通过访问其他进程ptrace()
,则它一次只能访问一个机器字,每个字使用一次昂贵的系统调用。
另一方面的 Procfs 提供了/proc/<pid>/as
文件中看到的进程的整个地址空间。在该文件上,read()
和write()
工作lseek()
,这使得对其他进程的访问更快。
但 procfs 还提供了更多有关进程的信息,而不仅仅是ptrace()
提供寄存器和地址空间访问,以及单步等类似功能。
该truss(1)
实用程序由 Roger Faulkner 编写,作为 procfs 的一部分。这是基于 1986 年 procfs 独有的另一个接口,但 SunOSptrace()
在 1988 年确实增强了系统调用,以提供相同的功能,而无需 procfs。 SunOS确实调用了相关程序trace(1)
。
Procfs 还提供/proc/<pid>/psinfo
了ps
命令。在procfs可用之前,ps
确实读取了/dev/kmem
有关进程的打印信息,并且检索此类信息的方式使其不可靠。
顺便说一句:如果您想通过 procfs 单步执行另一个进程,这是通过ioctl()
procfs 中的 ona 文件完成的,同时ptrace()
提供一个子命令作为系统调用来执行相同的操作。今天ptrace()
是作为 procfs 功能的 libc 包装器来实现的。
另请注意,Solaris 不仅提供 procfs,而且 Sun Microsystems 还雇用了罗杰·福克纳procfs的发明者。这是他与其他人一起发展的地方进程文件系统2。
Linux 提供的 procfs 既不兼容过程1也不进程文件系统2。
要检查 Solaris 是否通过 procfs 实现 ptrace,请参阅:https://sourceforge.net/p/schillix-on/schillix-on/ci/default/tree/usr/src/lib/libc/i386/sys/ptrace.c