Summary: | std::exception not catched when -O3 (-Os is fine, link static, FreeBSD 9.0-RELEASE-p3) | ||
---|---|---|---|
Product: | gcc | Reporter: | David Keller <david.keller> |
Component: | target | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | UNCONFIRMED --- | ||
Severity: | normal | Keywords: | EH |
Priority: | P3 | ||
Version: | 4.8.0 | ||
Target Milestone: | --- | ||
Host: | Target: | x68_64-freebsd* | |
Build: | Known to work: | ||
Known to fail: | 4.7.2, 4.8.0 | Last reconfirmed: | |
Attachments: | Here is the faulty code. |
Description
David Keller
2012-08-15 02:01:24 UTC
Err: Pasted command line show use of -Os which does *NOT* reproduce the behavior. Please use -O3. 1 #include <iostream> 2 #include <boost/system/error_code.hpp> 3 #include <boost/system/system_error.hpp> 4 5 6 namespace detail { 7 8 inline void throw_error(const boost::system::error_code& err) 9 { 10 /** 11 * If this condition is removed, (i.e. always throw) 12 * Then the exception will be caught!! 13 */ 14 if ( err ) 15 { 16 boost::system::system_error e(err); 17 throw e; 18 } 19 } 20 21 } // namespace detail 22 23 /** 24 * This exception is not catchable ! 25 */ 26 void 27 do_throw_bad 28 ( void ) 29 { 30 // Simulate a boost::asio::error 31 detail::throw_error( boost::system::errc::make_error_code( boost::system::errc::address_in_use )); 32 } 33 34 /** 35 * Now the exceptions thrown becomes catchable. 36 * When the function lives in an anonymous namespace. 37 */ 38 namespace { 39 40 void 41 do_throw_ok 42 ( void ) 43 { 44 // Simulate a boost::asio::error 45 detail::throw_error( boost::system::errc::make_error_code( boost::system::errc::address_in_use )); 46 } 47 48 } // anonymous namespace 49 [...] When the if condition is removed from the throw_error function, the exception is caught! I'll continue to simplify the case. Can you remove the boost dependency? Also does this work with the shared libgcc? I'am trying. It's not reproducible with <system_error> classes. Static build seems to use shared libgcc_s: $ldd bin/gcc-4.7/release/link-static/threading-multi/main bin/gcc-4.7/release/link-static/threading-multi/main: libstdc++.so.6 => /usr/local/lib/gcc47/libstdc++.so.6 (0x80084d000) libm.so.5 => /lib/libm.so.5 (0x800b55000) libgcc_s.so.1 => /usr/local/lib/gcc47/libgcc_s.so.1 (0x800d76000) libthr.so.3 => /lib/libthr.so.3 (0x800f8b000) libc.so.7 => /lib/libc.so.7 (0x8011ae000) Shared build reproduces. 1 #include <iostream> 2 #include <stdexcept> 3 4 namespace detail { 5 6 inline void throw_error(bool t) 7 { 8 /** 9 * If this condition is removed, (i.e. always throw) 10 * Then the exception will be catched !! 11 */ 12 if ( t ) 13 { 14 std::runtime_error e("failed"); 15 throw e; 16 } 17 } 18 19 inline void this_function_is_required ( void ) 20 { 21 std::cout << "do not remove on optimization" << std::endl; 22 } 23 24 } // namespace detail 25 26 /** 27 * This exception is not catchable ! 28 */ 29 void 30 do_throw_bad 31 ( bool b ) 32 { 33 // Simulate a boost::asio::error 34 //boost::system::errc::make_error_code( boost::system::errc::address_in_use ); 35 detail::this_function_is_required(); 36 detail::throw_error( b ); 37 } 38 39 /** 40 * Expect: 41 * ############# 42 * catched bad 43 * ############ 44 * 45 * But see: 46 * ############# 47 * terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::system::system_error> >' 48 * what(): asio: End of file 49 * Abort trap (core dumped) 50 * ############# 51 */ 52 int 53 main 54 ( int argc 55 , char* argv[] ) 56 { 57 try 58 { 59 do_throw_bad( argc == 1 ); 60 } 61 catch ( std::exception const& ) 62 { 63 std::cout << "catched" << std::endl; 64 } 65 66 return 0; 67 } 68 Et voilĂ Created attachment 28018 [details]
Here is the faulty code.
# Hum, without this variable, the program runs fine.
# Is it finding the wrong version of stdlib ?
setenv LD_LIBRARY_PATH /lib:/usr/local/bin:/usr/local/lib:/usr/local/lib32:/usr/local/lib64
g++47 -O3 -Wl,-rpath,/usr/local/lib/gcc47 main.cpp && ./a.out
It might be related to a wrong stdlib selection on my side: 1) Without setenv LD_LIBRARY_PATH /lib:/usr/local/bin:/usr/local/lib:/usr/local/lib32:/usr/local/lib64, the program runs fine. 2) It is linked with -rpath,/usr/local/lib/gcc48 (and rpath should have priority over LD_LIBRARy_PATH) *) Why optimization level has an influence on all this ? According to http://www.freebsd.org/cgi/query-pr.cgi?pr=28191, the man is wrong, FreeBSD look at LD_LIBRARY_PATH before rpath. So, when LD_LIBRARY_PATH contains /lib:, it crashes as seen in this thread. The test program picks the wrong lib libgcc_s ! Not a GCC bug then :-) Do you agree ? (I don't get why O3 makes program requiring the last libgcc_s, I'll expect it to be required regardless of optimization level) |