Bug 1222110

Summary: std::terminate incorrectly called on x86 when throwing an exception in a stacktrace that includes a C function
Product: Red Hat Enterprise Linux 6 Reporter: Dave Johansen <davejohansen>
Component: gccAssignee: Jakub Jelinek <jakub>
Status: CLOSED NOTABUG QA Contact: qe-baseos-tools-bugs
Severity: high Docs Contact:
Priority: unspecified    
Version: 6.6CC: mfranc, mpolacek
Target Milestone: rc   
Target Release: ---   
Hardware: i686   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2015-05-18 11:51:03 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
C file to test exception handling
none
C++ file to test exception handling none

Description Dave Johansen 2015-05-15 19:03:35 UTC
Created attachment 1026015 [details]
C file to test exception handling

Description of problem:
std::terminate() is being called and killing the program instead of the expected behavior of unwinding the stack and calling destructors.

Version-Release number of selected component (if applicable):
4.4.7-11

How reproducible:
Always

Steps to Reproduce:
1. gcc -g -nostdlib -c test_exception.c -o test_exception_c.o
2. g++ -g -nostdlib -c test_exception.cpp -o test_exception_cpp.o
3. g++ -g test_exception_c.o test_exception_cpp.o -o test_exception
4. ./test_exception

Actual results:
Program aborts/core dumps.

Expected results:
Exception handled in normal manner by unwinding the stack.

Additional info:
This only happens on x86 (x64 handles the exception as expected).
When built on x86 Fedora 21 with gcc 4.9.2-6 the exception is also handled as expected but when the executable built on RHEL 6 is run on Fedora 21, it aborts just like on RHEL 6.

Comment 1 Dave Johansen 2015-05-15 19:04:09 UTC
Created attachment 1026016 [details]
C++ file to test exception handling

Comment 3 Dave Johansen 2015-05-16 03:40:19 UTC
I apologize, the -nostdlib is not necessary. It was part of a test I was doing before submitting the bugzilla and it accidentally crept in here. The "Steps to Reproduce" should be (but I believe it doesn't really make any difference):
1. gcc -g -c test_exception.c -o test_exception_c.o
2. g++ -g -c test_exception.cpp -o test_exception_cpp.o
3. g++ -g test_exception_c.o test_exception_cpp.o -o test_exception
4. ./test_exception

Comment 4 Dave Johansen 2015-05-16 04:54:25 UTC
In case it's helpful, g++ 4.5.1-4 from Fedora 14 is the most recent version that I was able to reproduce the problem with. g++ 4.6.3-2 from Fedora 16 demonstrated the correct/expected behavior of unwinding the stack and not calling terminate.

Comment 5 Jakub Jelinek 2015-05-18 11:51:03 UTC
When compiling C++, the compiler defaults to -fexceptions, while for C the default is -fno-exceptions.  To be able to throw through C frames, you need them to be compiled with -fexceptions, or -funwind-tables, or -fasynchronous-unwind-tables.  Later compilers default to -fasynchronous-unwind-tables on more architectures than older ones, and -fasynchronous-unwind-tables has been the default on x86_64 far earlier than on i686.
For simply throwing through, you don't really need asynchronous unwind tables though, just -fexceptions or -funwind-tables should be good enough.

Comment 6 Dave Johansen 2015-05-18 15:35:13 UTC
Thanks for the clarification and sorry for the noise based on my lack of knowledge. Just for the sake of documentation, adding -fexceptions when building test_exception.c fixes the issue on RHEL 6/gcc 4.4.7-11 and RHEL 5.11/gcc 4.1.2-55 but didn't work on RHEL 5.3/gcc 4.1.2-44. So I'm guessing that some fix between release 44 and 55 fixed this issue on RHEL 5.