我正在编写一个程序来监视系统调用(除其他外)。但是我在让 ptrace 识别我传递给它的进程 ID 时遇到了一些麻烦。执行程序后,我收到此错误消息:
:No such process
但是,我已经在调用之前验证了进程 ID,方法是将其打印到控制台并使用 ps -all
进行验证。
以下是一些可能相关的代码(如有必要,我可以发布更多代码):
领导子进程:
/* Call to be traced */
if (ptrace (PTRACE_TRACEME, 0, 0, 0) < 0){
perror ("Process couldn't be traced");
exit (-1);
}
/* Execute process image */
if (execv (ProcessArgs[0], &ProcessArgs[1]) < 0){
perror ("Couldn't execute process");
exit (-1);
}
在父进程的线程中:
DbgdProcess * _Process = ( DbgdProcess * ) _ProcessPass;
int SystemCall = 0,
Status = 0;
/* I have tried sleep(1) here to wait for PTRACE_ME to no avail */
while (!_Process->CloseSignal){
if ( wait (&Status) < 0) // error handler
if ( WIFEXITED (Status)) // error handler
if (!WIFSTOPPED (Status)) continue;
SystemCall = ptrace (PTRACE_PEEKUSER, _Process->ID, 4 * ORIG_RAX, 0);
if (SystemCall < 0) // error handler
printf ("Process made system call %d\n", SystemCall);
if (ptrace (PTRACE_CONT, _Process->ID, 0, 0) < 0) // error handler
}
有人可以向我解释这种行为吗?
一些额外的注意事项:
- 被调试的进程是父进程的直接子进程
- 我很确定这是一个 64 位编译,因为 sys/reg.h 只定义了 RAX
- 所有错误处理程序都包含一个 perror() 消息
更新:
我已经从手册页中读到:
Most ptrace commands (all except PTRACE_ATTACH, PTRACE_SEIZE, PTRACE_TRACEME, PTRACE_INTERRUPT, and PTRACE_KILL) require the tracee to be in a ptrace-stop, otherwise they fail with ESRCH.
我相信,ESRCH 给出了“没有这样的过程”的信息。因此,当我进行 ptrace 调用时,进程可能没有 ptrace 停止?
更新:
我正在测试这个 example 中的代码.在执行以下操作后,我确实让它工作了: - 将标题从更新为 - 将 (eax_orig * 4) 更改为 (rax_orig * 8)
但是这些更改也在我的程序中,但它仍然无法正常工作。
更新:
我的代码可以正常工作。我不完全确定为什么,但是在我在使用 ptrace(2) 进行轮询调用的同一线程中调用 PTRACE_ATTACH 后它开始工作。我想这意味着 ptrace 必须在父进程的同一线程中使用,但我不完全确定。我现在的问题是,有人知道这是不是真的吗?或者,如果不是,为什么 ptrace 会这样?
更新:
我找到了这个 link ,这似乎表明我的问题并非闻所未闻。
最佳答案
sleep(1) 有时是不够的;尝试 sleep (5)。
关于c - PTrace 无法识别子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16767832/