This bug has originally been reported on Glibc bugtracker: http://sourceware.org/bugzilla/show_bug.cgi?id=11670 Please look here first for a detailed description. The __sigsetjmp function returns twice so it's not allowed to reuse stack space of existing automatic variables after this function has been called. C-Code: --------- void *x = malloc(something); do { __pthread_unwind_buf_t __cancel_buf; void *y = x; int not_first_call = __sigsetjmp((struct __jmp_buf_tag *) (void *) __cancel_buf.__cancel_jmp_buf, 0); if (not_first_call) { free(y); __pthread_unwind_next (&__cancel_buf); /* NOTREACHED */ } do { ... } while (0); free(y); } while(0); In the resulting assembler code the second "free(y)" is "replaced" by "free(x)" and the stack space for y is used for something else. This causes problems when __sigsetjmp() returns the second time because the stack memory for "y" may already contain the value of another variable at this time. ASM output: --------- 120: ebfffffe bl 0 <malloc> 124: e50b0280 str r0, [fp, #-640] ; 0x280 <-- x is @ fp,0x280 128: e51bc280 ldr ip, [fp, #-640] ; 0x280 12c: e3a01000 mov r1, #0 130: e24b0f53 sub r0, fp, #332 ; 0x14c 134: e50bc2b8 str ip, [fp, #-696] ; 0x2b8 <-- y is @ fp,0x2b8 138: ebfffffe bl 0 <__sigsetjmp> ... 1f4: e50b52b8 str r5, [fp, #-696] ; 0x2b8 <-- y is overwritten ... 408: e51b0280 ldr r0, [fp, #-640] ; 0x280 <-- y has been 40c: ebffff15 bl 68 <thread_cancel0> replaced by x ---------
Created attachment 20925 [details] Preprocessed source compile with arm-linux-gnueabi-gcc -mcpu=arm920t -Os -o test.o -c test.i This file is a stripped down version of the original source. Here __sigsetjmp is used twice because pthread_cleanup_push()/pthread_cleanup_pop() are used nested: a = malloc(); pthread_cleanup_push(handler, a); x = malloc() pthread_cleanup_push(handler, x) ... pthread_cleanup_pop(1); pthread_cleanup_pop(1); The code is arranged in a way the the problem happens for both instances of __cancel_arg are affected. The bug is little bit "volatile", if you change the source it will usually disappear or move to another position. For instance you may try removing the marked line: comp_1 = 0.0; comp_2 = 0.0; for (i = 0; i < num_1 - delay1; ++i) { --> comp_1 += conj(comp_out[i]) * comp_out[i]; comp_2 += conj(comp_out[i]) * comp_in[i]; } siglongjmp() is only used for demonstration purposes. You can also link with "-pthreads -lm" to a full executable demo.
Created attachment 20926 [details] Object file (for reference)
you need to mark y and x volatile.
If the variable is not modified between setjmp and longjmp the compiler is required to preserve its value.
The __cancel_arg variables are pseudos until ira, apparently during IRA the 2 stack slots chosen for those are shared between __cancel_arg vars and other vars used later in the function. Do we need to act as if -fno-ira-share-spill-slots is set in cfun->calls_setjmp functions?
(In reply to comment #5) > Do we need to act as if > -fno-ira-share-spill-slots > is set in cfun->calls_setjmp functions? At least in my case "-Os -fno-ira-share-spill-slots" seems to solve the problem. This applies also to the original (not stripped down) version of the code.
(In reply to comment #6) > (In reply to comment #5) > > Do we need to act as if > > -fno-ira-share-spill-slots > > is set in cfun->calls_setjmp functions? > > At least in my case "-Os -fno-ira-share-spill-slots" seems to solve the > problem. This applies also to the original (not stripped down) version of the > code. > Is this still a bug then? Should ira-share-spill-slots be automatically disabled for the caller function when a callee function can return twice?
(In reply to comment #7) > Is this still a bug then? Should ira-share-spill-slots be automatically > disabled for the caller function when a callee function can return twice? > I've never tested with gcc-4.5.x, but in 4.4.x the problem is still present. Unfortunately -fno-ira-share-spill-slots seems to introduce another bug which leads to wrong computations (nearly at the same code position where I had the problems mentioned is this report). At this moment I can not provide a detailed report for this problem, but perhaps it's the same as http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40386.
(In reply to comment #8) > (In reply to comment #7) > > Is this still a bug then? Should ira-share-spill-slots be automatically > > disabled for the caller function when a callee function can return twice? > > > I've never tested with gcc-4.5.x, but in 4.4.x the problem is still present. > > Unfortunately -fno-ira-share-spill-slots seems to introduce another bug which > leads to wrong computations (nearly at the same code position where I had the > problems mentioned is this report). > > At this moment I can not provide a detailed report for this problem, but > perhaps it's the same as http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40386. > I've submitted a patch solving PR40386. So now we can solve this problem by preventing slot sharing when setjmp is used. I'll send a patch soon.
(In reply to comment #9) > I've submitted a patch solving PR40386. So now we can solve this problem by > preventing slot sharing when setjmp is used. > > I'll send a patch soon. Could you please send me both patches? I would like to test whether both problems are solved (at least for me). regards Christian
Subject: Bug 44554 Author: vmakarov Date: Thu Sep 9 13:53:32 2010 New Revision: 164102 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=164102 Log: 2010-09-09 Vladimir Makarov <vmakarov@redhat.com> PR middle-end/44554 * ira.c (ira): Switch off sharing spill slots if setjmp is called. Modified: trunk/gcc/ChangeLog trunk/gcc/ira.c
Subject: Bug 44554 Author: vmakarov Date: Thu Sep 9 13:55:35 2010 New Revision: 164105 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=164105 Log: 2010-09-09 Vladimir Makarov <vmakarov@redhat.com> PR middle-end/44554 * ira.c (ira): Switch off sharing spill slots if setjmp is called. Modified: branches/gcc-4_5-branch/gcc/ChangeLog branches/gcc-4_5-branch/gcc/ira.c
Subject: Bug 44554 Author: vmakarov Date: Thu Sep 9 13:58:24 2010 New Revision: 164107 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=164107 Log: 2010-09-09 Vladimir Makarov <vmakarov@redhat.com> PR middle-end/44554 * ira.c (ira): Switch off sharing spill slots if setjmp is called. Modified: branches/gcc-4_4-branch/gcc/ChangeLog branches/gcc-4_4-branch/gcc/ira.c
Created attachment 21901 [details] A patch that should fix it Please verify whether this fixes it.
(In reply to comment #14) > Created attachment 21901 [details] > A patch that should fix it > > Please verify whether this fixes it. Hasn't it already been fixed in comment #11? My plan was to wait until release of gcc-4.4.5 and test then. Are additional changes required to fix this bug?
Argh, wrong PR. I wanted 45445.
(In reply to comment #15) > (In reply to comment #14) > > Created attachment 21901 [details] > > A patch that should fix it > > > > Please verify whether this fixes it. > > Hasn't it already been fixed in comment #11? My plan was to wait until release > of gcc-4.4.5 and test then. Are additional changes required to fix this bug? gcc 4.4.5 was released in October. Please can you confirm if this is now fixed.
(In reply to comment #17) > gcc 4.4.5 was released in October. Please can you confirm if this is now > fixed. I think THIS bug is fixed in 4.4.5. Unfortunately I've still problems with wrong computations as already mentioned in comment #8. But this would either be related to PR40386 or it's another bug.
(In reply to comment #18) > (In reply to comment #17) > > gcc 4.4.5 was released in October. Please can you confirm if this is now > > fixed. > > I think THIS bug is fixed in 4.4.5. Unfortunately I've still problems with > wrong computations as already mentioned in comment #8. But this would either be > related to PR40386 or it's another bug. I think it's best to raise a new bug, and CC Vladimir Makarov and Jeff Law. It will help to hear about the specific issues you are still seeing within that bug report.