Reputation: 30795
Ok, here is what I want to achieve. I want the threadRoutine thread of the forked process to only start executing from a particular point as shown by the comment //Thread of the forked process should start executing from here. I use the same memory area for the stack of the original and forked threadRoutine. But I suspect that since the threadRoutine of the forked process does execute longjmp as I set cp_thread to 1, its stack starts to diverge from the threadRoutine of the original process and so it cannot jump where I intended.
How can I solve this problem, that is don't diverge the stacks of the original and threadRoutine of the forked process in the precence of longjmp for the forked process.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <setjmp.h>
pthread_attr_t attr;
int cp_thread = 0;
static jmp_buf buf;
pthread_barrier_t bar;
void make_jmp_if_req()
{
if ( cp_thread )
longjmp( buf, 1 );
}
void *threadRoutine(void *threadMsg)
{
size_t myStackSize;
void *stackAddr;
make_jmp_if_req();
printf("%d: TR:{stackAddr pointer = %lx, @threadRoutine = %lx}\n",
getpid(), stackAddr, threadRoutine );
pthread_attr_getstack(&attr,&stackAddr,&myStackSize);
setjmp( buf );
pthread_barrier_wait(&bar);
printf("%d: TR:stack address %p\n", getpid(), stackAddr);
printf("%d: TR:stack size is %x\n", getpid(), myStackSize);
//printf("%d\n",*((int *)stackAddr)); // <--------------------Causing segmentation fault..
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
size_t stacksize;
void *stackAddr;
int rc;
size_t i;
pthread_t thread;
pid_t pid;
pthread_attr_init(&attr);
// So that setjmp in the threadRoutine of the orignal process is called before
// longjmp from threadRoutine of the forked process.
pthread_barrier_init(&bar, NULL, 2);
stacksize = 0xC00000; //12582912;
stackAddr = malloc(stacksize);
printf("Main:{stackAddr = %lx}\n", stackAddr );
pthread_attr_setstack(&attr,stackAddr, stacksize);
pthread_attr_getstack(&attr,&stackAddr, &stacksize);
printf("Main:stack address %p\n",stackAddr);
printf("Main:stack size is %x\n",stacksize);
rc = pthread_create( &thread, &attr, threadRoutine, (void*)0 );
pthread_barrier_wait(&bar);
switch(pid = fork())
{
case -1:
printf("fork failed");
break;
case 0: // Child
printf( "Child pid() = %d\n", getpid() );
cp_thread = 1;
rc = pthread_create(&thread, &attr, threadRoutine,(void *)0);
break;
default:// Leader
printf( "Parent pid() = %d\n", getpid() );
//rc = pthread_create(&thread, &attr, threadRoutine,(void *)0);
}
if(rc)
{
printf("ERROR:return code from pthread_create %d\n",rc);
exit(-1);
}
pthread_exit(NULL);
}
Upvotes: 1
Views: 300
Reputation: 1
I think your problem is related to the fact that fork()
don't reproduce the threads (existing in the parent process which calls fork) in the child process. After a fork() only a single thread exist in the child process.
Also, you should always call setjmp
before longjmp
so your threadRoutine is incorrect. And of course, you should not longjmp into another thread.
Don't use threads with fork without enormous precautions. Learn more about pthread_atfork
.
And I don't really understand why you want to do all this. I still believe you should not code that way (or you are not enough explaining why you want to do that, and what for).
Regards.
Upvotes: 1