Subj : Re: segmentation fault while using setjmp To : comp.os.linux.development.system,comp.os.linux,comp.os.linux.questions From : joga2052 Date : Wed Jun 30 2004 09:36 pm Kasper Dupont wrote in message news:<40E0F149.31707CDD@wfbtxutyalwrmianeanaimlqcc.skrammel.yaboo.dk>... > naveen wrote: > > > > Hello *, > > > > Here I'm trying to switch control between three threads in a cycle - > > parent, child1, child2 in that order. > > setjmp is really not intended to be used for that. > May or may not work, but you still have some > tricky problems to take care of on your own. Most > notably stack creation. > > > But after the first cycle of execution i get a segmentation fault. I > > guess the problem is with the stack allocated for each thread. I tried > > increasing the stack size and i still get the segmentation fault, but > > this time after completing a few more cycles. > > Well, you really don't create a stack anywhere in > your program. You have an unused array in your create > function, which depending on compiler options may > change the stack frame layout of that function. > > So even if there were no other problems, you would > have threads stomping on each other's stacks. The > unused array may offset the stack pointer of your > child threads by some amount, but it looks like both > your child threads will be using exactly the same > stack area. > > The way the stack layout looks the parent might not > conflict with the child threads, but only as long as > it doesn't use more than 1024 bytes of stack. I don't > know exactly how much the functions you call require, > but that may explain why a larger stack works slightly > better. > > The two child threads using the same area for stack > is certainly going to be a problem. Probably not the > first time, when they are just starting. Because they > will initialize their own stack. But second time child > 1 is scheduled, it might only work because the contents > of the two children's stacks would have been so > similar anyway. > > There is also a lot of race conditions in your code. In > your setup you setup a signal handler, that relies on > data structures, that have not yet been initialized. I > would have said thread creation should be done in a > critical region, but your design is so inflexible, that > the scheduling code couldn't even work before the > threads have been created. > > Besides I'm not sure fprintf is thread safe in the way > you try to use it. In that case you'd have races all the > time. I'd protect stderr by another critical region. > > No matter how you want to do, you have to allocate stacks > and setup stack pointers correctly. And I don't know any > portable way to do that. > > > Can anybody explain this: > > > > #include > > #include > > #include > > #include > > > > sigjmp_buf context[3]; > > int crt = 0; > > > > void parent() > > { > > while(1) > > fprintf(stderr, "Parent process\n"); > > } > > > > void child(int *i) > > { > > while(1) > > fprintf(stderr, "Child process %d\n", *i); > > } > > > > /* create child context and return to parent */ > > void create(int i) > > { > > if (sigsetjmp(context[i], 1)) { > > child(&crt); > > } else { > > char stack[1024]; > > siglongjmp(context[0], -1); > > } > > } > > > > /* context switch */ > > void run_thread() > > { > > int next = (crt + 1) % 3; > > > > if (!sigsetjmp(context[crt], 1)) { > > crt = next; > > siglongjmp(context[crt], -1); > > } > > } > > > > void handler(int sig) > > { > > signal(SIGALRM, handler); > > alarm(1); > > > > run_thread(); > > } > > > > main() > > { > > signal(SIGALRM, handler); > > alarm(1); > > > > if (!sigsetjmp(context[0], 1)) { > > create(1); > > } > > if (!sigsetjmp(context[0], 1)) { > > create(2); > > } > > parent(); > > } i realize that there are a lot of pitfalls while using the setjmp/longjmp pair for multithreading. Portability is not my first concern. i think i can use assembly code (386) for saving the registers and doing the context-switch. Please point me to some literature relating to this .