Subj : Re: segmentation fault while using setjmp To : comp.os.linux.development.system,comp.os.linux,comp.os.linux.questions From : Kasper Dupont Date : Tue Jun 29 2004 07:34 am 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(); > } -- Kasper Dupont -- der bruger for meget tid paa usenet. For sending spam use kasperd@kd.lir.dk and abuse@kd.lir.dk I'd rather be a hammer than a nail. .