Reputation: 3053
I am having a problem with the clone function in that it give me a segmentation fault after the 9th call to it. Program works fine until I get up to using 9+ threads.
here is my call to clone:
void **child_stack = (void **) malloc(SIGSTKSZ);
clone (func,
(child_stack + SIGSTKSZ),
CLONE_VM | CLONE_FILES | CLONE_PARENT_SETTID,
(void *) argsForFunc,
&pid);
I am using clone and not any higher level threads library like pthreads.
If it helps, this is the error I get when using GDB:
Program received signal SIGSEGV, Segmentation fault.
clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:66
66 movq %rcx,8(%rsi)
Current language: auto; currently asm
Upvotes: 1
Views: 281
Reputation: 213526
here is my call to clone
Don't do that. After you correct pointer arithmetic (as answered by Jay Conrod), your code will die horrible death due to a race condition, because you are not setting up TLS (thread-local storage) the way glibc expects it to be set up.
Effectively, if you use direct clone
calls, you can't ever call any of glibc functions (not even your own functions in another shared library (1)) in the new "thread", or you risk intermittent (and exceedingly hard to debug) failures. Just use pthread_create()
instead.
Here is the glibc bug showing the kinds of problems you'll run into (note that this is not a glibc problem).
(1) Because dynamic symbol resolution requires a trip into glibc.
Upvotes: 3
Reputation: 29701
TJD's comment above made me see the problem right away: your pointer arithmetic to get the end of the stack is incorrect. If you allocate the stack as:
void **child_stack = (void **) malloc(SIGSTKSZ);
And then you calculate the top of the stack as:
child_stack + SIGSTKSZ
The actual address passed to clone will be
child_stack + sizeof(void*)*SIGSTKSZ
Maybe you meant for child_stack
to have type char*
? sizeof(char)
is 1 by definition, so that would give you the right result.
Upvotes: 2