Description of problem: gcc generates incomplete unwind information despite the use of -fasynchronous-unwind-tables. The result is that thread cancellation fails in glibc. This shows itself in the compilation of cancellation.c on x86. I do not know whether other archs are affected since the other factors contributing to recognizing the problem are different. Only on x86 do we have a reproducer so far. The actual problem is a function exit in the middle of the code. The function uses a call frame end %ebp to handle it. The exit uses "leave;ret" to exit the function. But it does not, for the ret instruction, corrects the CFA offset in the .eh_frame section. Version-Release number of selected component (if applicable): gcc-4.3.1-2.x86_64 How reproducible: always Steps to Reproduce: 1.compile nptl/cancellation.c from glibc. Just a normal configuration for 686. 2. 3. Actual results: The __pthread_enable_asynccancel code contains this in the generated asm code: __pthread_enable_asynccancel: .LFB30: .loc 1 31 0 pushl %ebp .LCFI2: movl %esp, %ebp [...] .LVL6: leave ret .LVL7: [...] .long .LEFDE3-.LASFDE3 .LASFDE3: .long .LASFDE3-.Lframe1 .long .LFB30-. .long .LFE30-.LFB30 .uleb128 0x0 .byte 0x4 .long .LCFI2-.LFB30 .byte 0xe .uleb128 0x8 .byte 0x85 .uleb128 0x2 .byte 0x4 .long .LCFI3-.LCFI2 .byte 0xd .uleb128 0x5 .align 4 This .eh_frame translates to (shown using eu-readelf): [ 34] FDE length=24 cie=[ 0] CIE_pointer: 56 initial_location: 0x40 (offset: 0x173c) address_range: 0x51 (end offset: 0x178d) Program: advance_loc 1 to 0x173d def_cfa_offset 8 offset r5 (reg5) at cfa-8 advance_loc 2 to 0x173f def_cfa_register r5 (reg5) nop nop nop As can be seen, the setup of the stack frame is described, but it is missing that for the duration of the 'ret' instruction only the CFA offset is back to 4. Expected results: Unwind info taking 'leave' into account so that unwinding works even when it happens when the 'ret' instruction is currently executed. Additional info: I added a reference to the bug which has been filed against glibc because of this gcc problem. This is a pretty severe problem. It means that, in this specific case, some unwind handlers aren't executed. This includes for x86 the one locking the mutex in can pthread_cond_wait is interrupted. This is pretty severe.
Created attachment 329946 [details] Reduced test case This is a reduced test case. Compile it with gcc -m32 -O2 -march=core2 -fgnu89-inline -g -fPIC -fexceptions -fasynchronous-unwind-tables -c n.i If you leave out the -march=core2 gcc won't generate the leave instruction but the resulting code (using push/pop) still is wrong. So it is not the pattern for leave alone.
Yes, gcc doesn't generate unwind info for the epilogues. This is a known issue for several years, but it might be quite hard to implement it.
Richard, what is the status of the epilogue unwind info fix?
Fixed in rawhide.