我正在尝试使用原始克隆系统调用来避免将pid 0代码重构为一个函数。 Linux需要16个字节的堆栈,另外,libc保留16位,据推测可以存储ptid和ctid。 下面的代码创build一个alignment的堆栈然后退出小孩。 等待由libc的包装器克隆的孩子后,我使用原始系统调用与相同的缓冲区,但每次程序segfaults时使用原始系统调用。 附加是从strace的输出,除非我忽略任何东西显示系统调用参数是两次相同。 至less还有一个其他问题的原始克隆系统调用 SO,其中OP似乎有类似的困难,不幸的是,接受的答案使用libc克隆包装而不是系统调用。
#define _GNU_SOURCE #include <sched.h> #include <stdalign.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <syscall.h> #include <signal.h> #include <stdint.h> #include <errno.h> #include <string.h> #include <sys/wait.h> int test(void*c) { quick_exit(0); } int main(void) { alignas (16) unsigned char stack[4096] = {0}; printf("Top of stack %pn",stack+sizeof(stack)); printf("Top of stack minus 16 %pn",stack+sizeof(stack)-16); pid_t pid = clone(test,stack+sizeof(stack),CLONE_VM|SIGCHLD,0); wait(NULL); memset(stack,sizeof stack); pid = syscall(SYS_clone,stack+sizeof(stack)-16); if (pid == 0) quick_exit(0); wait(NULL); quick_exit(0); }
Strace输出:
clockley@ubuntu:~$ strace ./a.out execve("./a.out",["./a.out"],[/* 57 vars */]) = 0 brk(NULL) = 0x55b1e58ee000 access("/etc/ld.so.nohwcap",F_OK) = -1 ENOENT (No such file or directory) mmap(NULL,12288,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0) = 0x7f70303a0000 access("/etc/ld.so.preload",R_OK) = -1 ENOENT (No such file or directory) open("/opt/google/chrome/tls/x86_64/libc.so.6",O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/opt/google/chrome/tls/x86_64",0x7ffcc0e2e400) = -1 ENOENT (No such file or directory) open("/opt/google/chrome/tls/libc.so.6",O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/opt/google/chrome/tls",0x7ffcc0e2e400) = -1 ENOENT (No such file or directory) open("/opt/google/chrome/x86_64/libc.so.6",O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/opt/google/chrome/x86_64",0x7ffcc0e2e400) = -1 ENOENT (No such file or directory) open("/opt/google/chrome/libc.so.6",O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/opt/google/chrome",{st_mode=S_IFDIR|0755,st_size=4096,...}) = 0 open("/opt/google/chrome/lib/tls/x86_64/libc.so.6",O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/opt/google/chrome/lib/tls/x86_64",0x7ffcc0e2e400) = -1 ENOENT (No such file or directory) open("/opt/google/chrome/lib/tls/libc.so.6",O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/opt/google/chrome/lib/tls",0x7ffcc0e2e400) = -1 ENOENT (No such file or directory) open("/opt/google/chrome/lib/x86_64/libc.so.6",O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/opt/google/chrome/lib/x86_64",0x7ffcc0e2e400) = -1 ENOENT (No such file or directory) open("/opt/google/chrome/lib/libc.so.6",O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/opt/google/chrome/lib",0x7ffcc0e2e400) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache",O_RDONLY|O_CLOEXEC) = 3 fstat(3,{st_mode=S_IFREG|0644,st_size=171231,...}) = 0 mmap(NULL,171231,PROT_READ,MAP_PRIVATE,3,0) = 0x7f7030376000 close(3) = 0 access("/etc/ld.so.nohwcap",F_OK) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libc.so.6",O_RDONLY|O_CLOEXEC) = 3 read(3,"177ELF2113 3 >