微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

原始克隆系统调用不能正常工作

我正在尝试使用原始克隆系统调用来避免将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,"177ELF21133>12052"...,832) = 832 fstat(3,{st_mode=S_IFREG|0755,st_size=1856752,3959200,PROT_READ|PROT_EXEC,MAP_PRIVATE|MAP_DENYWRITE,0) = 0x7f702fdb7000 mprotect(0x7f702ff74000,2097152,PROT_NONE) = 0 mmap(0x7f7030174000,24576,MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE,0x1bd000) = 0x7f7030174000 mmap(0x7f703017a000,14752,MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS,0) = 0x7f703017a000 close(3) = 0 mmap(NULL,8192,0) = 0x7f7030374000 arch_prctl(ARCH_SET_FS,0x7f7030374700) = 0 mprotect(0x7f7030174000,16384,PROT_READ) = 0 mprotect(0x55b1e46da000,4096,PROT_READ) = 0 mprotect(0x7f70303a3000,PROT_READ) = 0 munmap(0x7f7030376000,171231) = 0 fstat(1,{st_mode=S_IFCHR|0620,st_rdev=makedev(136,8),...}) = 0 brk(NULL) = 0x55b1e58ee000 brk(0x55b1e590f000) = 0x55b1e590f000 write(1,"Top of stack 0x7ffcc0e2ecd0n",28Top of stack 0x7ffcc0e2ecd0 ) = 28 write(1,"Top of stack minus 16 0x7ffcc0e2"...,37Top of stack minus 16 0x7ffcc0e2ecc0 ) = 37 clone(child_stack=0x7ffcc0e2ecc0,flags=CLONE_VM|SIGCHLD) = 122458 wait4(-1,NULL,NULL) = 122458 --- SIGCHLD {si_signo=SIGCHLD,si_code=CLD_EXITED,si_pid=122458,si_uid=1000,si_status=0,si_utime=0,si_stime=0} --- clone(child_stack=0x7ffcc0e2ecc0,flags=CLONE_VM|SIGCHLD) = 122459 exit_group(0 <unfinished ...> +++ killed by SIGSEGV +++ Segmentation fault (core dumped)

如何debuggingWinsock API调用

在C中实现多个pipe道

如何在operator new中使用unique_ptr

如何将C / C ++中的Linux应用程序变成Linux发行版的桌面环境?

C ++代码用FindFirstFile / FindNextFile删除文件夹中的所有文件

Linux中的平滑closures服务器套接

如何使一个应用程序有一个窗体,但不是一个窗体?

Unix中包含两个hashtags的文件types是什么?

如何正确加载基于Windows版本的GetMappedFileName

我可以使用xbuild在Linux上编译一个Visual C ++项目吗?

syscall没有clone特殊知识。 这意味着当函数试图在新创建的线程中返回时,它会从被切换的堆栈读取返回地址,该地址为零。 如果您向堆栈写入非零位模式并放弃CLONE_VM ,则这一点更为明显,因此子项不会CLONE_VM父项。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐