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
---------
--
Summary: Stack space after sigsetjmp is reused
Product: gcc
Version: 4.4.4
Status: UNCONFIRMED
Severity: major
Priority: P3
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: christian dot eggers at kathrein dot de
GCC build triplet: x86_64-unknown-linux-gnu
GCC host triplet: x86_64-unknown-linux-gnu
GCC target triplet: arm-linux-gnueabi
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44554