linux - 使用 waitid 系统调用在汇编中等待克隆的 child

标签 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 的循环,它最终会给出等待 child 的预期结果。这使我相信存在某种竞争条件, child 尚未正确开始,但已获得 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,我怀疑我需要正确设置该结构以使一切正常,但我还没有找到任何关于如何在汇编中做到这一点的例子。我怎样才能做到这一点?还是我弄错了,我只需要求助于我提到的循环解决方法?

最佳答案

在这种情况下,需要添加 flags=SIGCHLD | ... 当调用 clone 时,SIGCHLD 由 child 在退出时发送,如 include/uapi/linux/sched.h 中所述.

此 GAS 代码仅适用于 SIGCHLD

.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

关于linux - 使用 waitid 系统调用在汇编中等待克隆的 child ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40715968/

相关文章:

linux - 在 Visual Studio Code 中调试时出现未绑定(bind)方法异常

linux - 命令替换在通过 SSH 传递的脚本文本中不起作用

linux - 动态库查找ld的规则是什么?

c - ARM程序集插入排序中的无效指针问题

c - 用 C 制作一个小的 mach-o 可执行文件

c - STM32F4 不压入/弹出浮点寄存器

gcc - 比例索引寻址模式是一个好主意吗?

linux - 用于循环和删除的 Shell 脚本

.net - 系统.BadImageFormatException : Could not load file or assembly (from installutil. exe)

debugging - 我应该使用 Windbg_x86 在 64 位 Windows 中调试 32 位应用程序吗?