#define _GNU_SOURCE #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> void func(); void main(int argc,char **argv) { printf("i am main\n"); int clone_flag,arg,retval; char *stack; clone_flag=CLONE_VM|CLONE_SIGHAND; stack=(char*)malloc(4096); retval=clone((void*)func,&(stack[4095]),clone_flag,NULL); stack=(char*)malloc(4096); retval=clone((void*)func,&(stack[4095]),clone_flag,NULL); } void func() { int i; for(i=0;i<3;i++) { printf("i: %d\n ",i); } } output:
i am main i: 0 i: 1 strace -f
5915 fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(4, 1), ...}) = 0 5915 ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0 5915 brk(NULL) = 0xaf2000 5915 brk(0xb14000) = 0xb14000 5915 write(1, "i am main\n", 10) = 10 5915 clone(child_stack=0xaf400f, flags=CLONE_VM|CLONE_SIGHAND) = 5916 5915 clone(child_stack=0xaf501f, flags=CLONE_VM|CLONE_SIGHAND) = 5917 5915 exit_group(5917) = ? 5915 +++ exited with 29 +++ 5917 write(1, "i", 1) = 1 5917 write(1, ": 0\n ", 5) = 5 5917 write(1, "i", 1) = 1 5917 write(1, ": 1\n ", 5) = 5 5916 --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0xaf194f} --- 5916 +++ killed by SIGSEGV (core dumped) +++ 5917 +++ killed by SIGSEGV +++ gdb ./a.out core
Core was generated by `./a.out'. Program terminated with signal SIGSEGV, Segmentation fault. #0 buffered_vfprintf (s=0x7f737fd43620 <_IO_2_1_stdout_>, format=0x40074e "i: %d\n ", args=0x1f49f27) at vfprintf.c:2299 2299 vfprintf.c: No such file or directory. [Current thread is 1 (LWP 6280)] (gdb) where #0 buffered_vfprintf (s=0x7f737fd43620 <_IO_2_1_stdout_>, format=0x40074e "i: %d\n ", args=0x1f49f27) at vfprintf.c:2299 #1 0x00007f737f9cb32d in _IO_vfprintf_internal ( s=0x7f737fd43620 <_IO_2_1_stdout_>, format=0x40074e "i: %d\n ", ap=ap@entry=0x1f49f27) at vfprintf.c:1293 #2 0x00007f737f9d3899 in __printf (format=<optimized out>) at printf.c:33 #3 0x00000000004006a8 in func () at code.c:23 #4 0x00007f737fa8541d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109 it is confusing if I remove the"printf("i am main\n");" the code will run well
strace
5937 brk(NULL) = 0x1f75000 5937 brk(0x1f97000) = 0x1f97000 5937 clone(child_stack=0x1f75fff, flags=CLONE_VM|CLONE_SIGHAND) = 5938 5937 clone(child_stack=0x1f7700f, flags=CLONE_VM|CLONE_SIGHAND) = 5939 5937 exit_group(5939) = ? 5937 +++ exited with 51 +++ 5939 fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(4, 1), ...}) = 0 5939 ioctl(1, TCGETS, {B38400 opost isig icanon echo ...}) = 0 5939 write(1, "i: 0\n", 5) = 5 5939 write(1, " i: 1\n", 6) = 6 5939 write(1, " i: 2\n", 6) = 6 5938 write(1, " i: 2\ni: 0\n", 11) = 11 5939 exit_group(6) = ? 5939 +++ exited with 6 +++ 5938 write(1, " i: 1\n", 6) = 6 5938 write(1, " i: 2\n", 6) = 6 5938 exit_group(6) = ? 5938 +++ exited with 6 +++ why the "printf" makes such a big difference?(by the way,why the SIGSEGV killed another process?)
&(stack[4095])is probably misaligned for use as a stack pointer. Try it with&(stack[4096])instead.clone? Why notpthread_createorfork?int func(void*), notvoid func().