父母过程的追踪

subprocess可以使用ptrace系统调用来跟踪其父进程吗?

Os是linux 2.6

谢谢。

upd1:我想从“本身”跟踪process1。 这是不可能的,所以我做fork,并尝试从subprocess执行ptrace(process1_pid, PTRACE_ATTACH) 。 但是我不能,有一个奇怪的错误,像内核禁止孩子追踪他们的父进程

UPD2:这种跟踪可以被安全策略所禁止。 哪些政策这样做? 内核中的检查代码在哪里?

UPD3:在我的embedded式Linux上,我没有PEEKDATA的错误,但没有GETREGS的错误:

 child: getregs parent: -1 errno is 1, strerror is Operation not permitted 

errno = EPERM

这个问题真的让我感兴趣。 所以我写了一些代码来试用。

首先要记住,跟踪一个进程时,除了名字(即getppid() )外,跟踪进程成为大多数目的的父进程。 首先,手册的PTRACE_ATTACH部分的PTRACE_ATTACH内容很有帮助:

  PTRACE_ATTACH Attaches to the process specified in pid, making it a traced "child" of the calling process; the behavior of the child is as if it had done a PTRACE_TRACEME. The calling process actually becomes the parent of the child process for most purposes (eg, it will receive notification of child events and appears in ps(1) output as the child's parent), but a getppid(2) by the child will still return the PID of the original parent. The child is sent a SIGSTOP, but will not necessarily have stopped by the completion of this call; use wait(2) to wait for the child to stop. (addr and data are ignored.) 

现在这里是我写的代码来测试和验证,你可以实际上ptrace()你的父母(你可以通过将其转储到一个名为blah.c的文件并运行make blah来构建:

 #include <assert.h> #include <stdio.h> #include <unistd.h> #include <sys/ptrace.h> int main() { pid_t pid = fork(); assert(pid != -1); int status; long readme = 0; if (pid) { readme = 42; printf("parent: child pid is %d\n", pid); assert(pid == wait(&status)); printf("parent: child terminated?\n"); assert(0 == status); } else { pid_t tracee = getppid(); printf("child: parent pid is %d\n", tracee); sleep(1); // give parent time to set readme assert(0 == ptrace(PTRACE_ATTACH, tracee)); assert(tracee == waitpid(tracee, &status, 0)); printf("child: parent should be stopped\n"); printf("child: peeking at parent: %ld\n", ptrace(PTRACE_PEEKDATA, tracee, &readme)); } return 0; } 

请注意,我正在利用父虚拟地址空间的复制知道去哪里看。 另外请注意,当孩子终止时,我怀疑有一个隐含的分离,必须让父母继续,我没有进一步调查。

是的,这是可能的…甚至GETREGS的作品。 检查x86(基于马特乔伊纳代码,谢谢他)

 #include <assert.h> #include <stdio.h> #include <unistd.h> #include <sys/ptrace.h> #include <sys/types.h> #include <sys/user.h> int main() { pid_t pid = fork(); // assert(pid != -1); int status; long readme = 0; struct user_regs_struct regs; if (pid) { readme = 42; printf("parent: child pid is %d\n", pid); assert(pid == wait(&status)); printf("parent: child terminated?\n"); assert(0 == status); } else { pid_t tracee = getppid(); printf("child: parent pid is %d\n", tracee); sleep(1); // give parent time to set readme assert(0 == ptrace(PTRACE_ATTACH, tracee)); assert(tracee == waitpid(tracee, &status, 0)); printf("child: parent should be stopped\n"); printf("child: peeking at parent: %ld\n", ptrace(PTRACE_PEEKDATA, tracee, &readme, NULL)); printf("Regs was %p, %p, %p, %p; &status is %p \n", regs.eax, regs.ebx, regs.ecx, regs.edx, &status); printf("child: getregs parent: %ld\n", ptrace(PTRACE_GETREGS, tracee, NULL, &regs)); printf("Regs is %p, %p, %p, %p; &status is %p \n", regs.eax, regs.ebx, regs.ecx, regs.edx, &status); } return 0; } 

结果:

 child: parent pid is 1188 parent: child pid is 1189 child: parent should be stopped child: peeking at parent: 42 Regs was (nil), (nil), (nil), (nil); &status is 0xbfffea50 child: getregs parent: 0 Regs is 0xfffffe00, 0xffffffff, 0xbfffea50, (nil); &status is 0xbfffea50 parent: child terminated?