等待克隆的孩子在装配中使用waitid系统调用

时间:2016-11-21 08:46:59

标签: linux assembly x86-64

我正在尝试等待我克隆的进程。但是,当父级将系统调用发送到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找到了关于如何在汇编中做到这一点的任何例子。我怎样才能做到这一点?或者我错了,我只需要采用我提到的循环解决方法?

1 个答案:

答案 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