user972276
user972276

Reputation: 3053

9th call to clone produces seg fault

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

Answers (2)

Employed Russian
Employed Russian

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

Jay Conrod
Jay Conrod

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

Related Questions