我正在尝试等待我克隆的进程。但是,当父级将系统调用发送到waitid
时,我在使用strace时得到-1 ECHILD
。尽管克隆调用返回了创建的子节点的PID,如下所示:
clone(child_stack=0x7ffe2b412d10, flags=CLONE_NEWNS|CLONE_NEWUTS|CLONE_NEWIPC|CLONE_NEWPID) = 3735
waitid(P_PID, 3735, NULL, WEXITED, NULL) = -1 ECHILD (No child processes)
如果我创建一个反复调用waitid
的循环,它最终会给出等待孩子的预期结果。这让我相信有一些竞争条件,孩子还没有正常开始,但已经获得了PID。
以下是相关的汇编代码:
_start:
mov rax, SYS_CLONE
mov rdi, CLONE_FLAGS
mov rsi, rsp
mov rdx, 0
mov r10, 0
syscall
cmp rax, 0
je _clone
mov rdi, PPID
mov rsi, rax ; pid
mov rdx, 0
mov r10, 4 ; exited
mov rax, SYS_WAITID
syscall
mov rdi, OK_EXIT
jmp _exit
_clone:
mov rax, SYS_EXECVE
mov rdi, [rsp + 16]
lea rsi, [rsp + 16]
lea rdx, [rsp + 40]
syscall
mov rdi, rax
jmp _exit
_exit:
mov rax, SYS_EXIT
syscall
请注意,我将NULL作为第三个(siginfo_t *infop
)参数传递给waitid
,我怀疑我需要正确设置该结构以使一切正常,但我还没有#39 ; t找到了关于如何在汇编中做到这一点的任何例子。我怎样才能做到这一点?或者我错了,我只需要采用我提到的循环解决方法?
答案 0 :(得分:1)
在这种情况下,需要在调用flags=SIGCHLD | ...
时添加clone
,以便孩子在退出时SIGCHLD
发送SIGCHLD
,如include/uapi/linux/sched.h中所述。
此GAS代码仅适用于.globl _start
.text
a:.quad 1
.quad 0
b:.quad d
c:
mov $56,%rax
#SIGCHLD
mov $17,%rdi
mov $b,%rsi
syscall
ret
d:
mov $35,%rax
mov $a,%rdi
syscall
mov $60,%rax
syscall
_start:
call c
mov %rax,%rsi
mov $247,%rax
mov $1,%rdi
mov $4,%r10
syscall
mov $60,%rax
syscall
TreeView