我无法弄清楚为什么函数返回"没有这样的过程"每次运行它时都会出现错误消息,但只需使用相同的内联指令就可以生成所需的输出。
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
void getregs(pid_t proc, struct user_regs_struct *regs);
int main() {
pid_t proc = fork();
if(proc == 0) {
if(ptrace(PTRACE_TRACEME, 0, NULL, NULL) == -1) {
perror("traceme");
exit(0);
}
if(execl("child", "child", NULL) == -1) {
perror("execl");
exit(0);
}
} else {
wait(&proc);
struct user_regs_struct regs;
ptrace(PTRACE_GETREGS, proc, NULL, ®s);
printf("eax: %08x\n", (unsigned int)regs.eax);
getregs(proc, ®s);
ptrace(PTRACE_CONT, proc, NULL, NULL);
}
return 0;
}
void getregs(pid_t proc, struct user_regs_struct *regs) {
if(ptrace(PTRACE_GETREGS, proc, NULL, ®s) == -1) {
perror("GETREGS");
exit(1);
}
printf("eax: %08x\n", (unsigned int)regs->eax);
}
当我跑步时,我得到了
~$ ./tracer
eax: 0000002f
GETREGS: No such process
我不明白为什么getregs()
会返回该错误。它几乎就像是在某种范围之外?
此外,有些不相关的内容:无论我尝试0000002f
的过程是什么,EAX始终设置为execl()
。这很自然吗?我不知道我是否正确分配了孩子的过程。我是否需要就此问题提出新的问题?
答案 0 :(得分:5)
您遇到此错误是因为您正在通过将其地址传递给wait(2)
系统调用来修改变量proc
中包含的进程标识符(PID)的值。
wait
系统调用将在子进程终止时更改proc
的值以及子进程的返回状态。因此,当您使用ptrace
在proc
中引用您的子流程时,其值可能无效并且不会引用任何现有流程。
当 @lornix 注意到时,请确保将正确的指针传递给ptrace
函数中的getregs
。
答案 1 :(得分:3)
void getregs(pid_t proc, struct user_regs_struct *regs) {
if(ptrace(PTRACE_GETREGS, proc, NULL, ®s) == -1) {
您需要在ptrace调用中取消引用regs。 (在这种情况下删除&amp; )
if(ptrace(PTRACE_GETREGS, proc, NULL, regs) == -1) {
你用regs的ADDRESS调用getregs,所以getregs&#39; regs不是主代码中的结构,它是指向结构的指针。
编辑:想通了
您在等待通话中使用/重新分配 proc ,不应该这样做。要等待的参数是状态值,而不是特定子项的pid。等待等待 任何子项,请参阅 waitpid 以获取特定于pid的等待。
尝试:
int wait_status;
wait(&wait_status);
代替当前的等待函数调用。
答案 2 :(得分:1)
您的ptrace
来电都表现得一样。不同之处在于您忽略了内联函数的返回值,而检查了函数中的函数。
EAX
值是一个红色鲱鱼:由于PTRACE_GETREGS
失败,结构未初始化。
wait
函数不带进程ID。它等待某个进程终止并将其状态置于由指针传入的整数值中。
您想要waitpid
(如果您想等待特定的子进程)。当您知道只有一个函数时,简单函数wait
很有用:
int status;
if (wait(&status)) { ... }