有人添加到
Wikipedia "ptrace" article
声称在Linux上,一个ptraced进程本身不能ptrace另一个进程。我正试图确定是否(如果是,为什么)是这样。下面是一个简单的程序,我设计来测试这个。我的程序失败了(子进程没有正常运行),但我非常确信这是我的错误,而不是根本原因。
实质上,最初的过程
一
叉子法
乙
依次分叉
C
.
一
让它的孩子
乙
,
乙
让它的孩子
C
. 一旦设置好,所有三个进程都将被写入
A
,
B
或
C
每秒一次。
实际上发生的是
一
和
乙
工作很好,但是
C
只打印一次然后就卡住了。核对
ps -eo pid,cmd,wchan
显示
C
陷入核心函数
ptrace_stop
其他人在的时候
hrtimer_nanosleep
我想这三个人都会在那里。
这三个程序偶尔都会工作(所以程序会打印cs以及as和bs),这使我相信在初始设置中存在一些竞争条件。
我的
猜测
至于可能的问题是:
-
有点关系
一
看到一个
SIGCHLD
有关
乙
看到一个
西格尔德
用信号做
C
,并等待(2)报告两者都来自
乙
(但是ptrace_cont对两个pids的一个恶意调用并不能解决问题)?
-
C
应该由
乙
-有
C
继承了ptrace
一
取而代之(和)
乙
打给ptrace的电话既没有出错也没有过度保护?
有人知道我做错了什么吗?谢谢。
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
static void a(){
while(1){
printf ("A\n");
fflush(stdout);
sleep(1);
}
}
static void b(){
while(1){
printf ("B\n");
fflush(stdout);
sleep(1);
}
}
static void c(){
while(1){
printf ("C\n");
fflush(stdout);
sleep(1);
}
}
static void sigchld_handler(int sig){
int result;
pid_t child_pid = wait(NULL); // find who send us this SIGCHLD
printf("SIGCHLD on %d\n", child_pid);
result=ptrace(PTRACE_CONT, child_pid, sig, NULL);
if(result) {
perror("continuing after SIGCHLD");
}
}
int main(int argc,
char **argv){
pid_t mychild_pid;
int result;
printf("pidA = %d\n", getpid());
signal(SIGCHLD, sigchld_handler);
mychild_pid = fork();
if (mychild_pid) {
printf("pidB = %d\n", mychild_pid);
result = ptrace(PTRACE_ATTACH, mychild_pid, NULL, NULL);
if(result==-1){
perror("outer ptrace");
}
a();
}
else {
mychild_pid = fork();
if (mychild_pid) {
printf("pidC = %d\n", mychild_pid);
result = ptrace(PTRACE_ATTACH, mychild_pid, NULL, NULL);
if(result==-1){
perror("inner ptrace");
}
b();
}
else {
c();
}
}
return 0;
}