Re: g++: -fno-rtti breaks polymorphic catch on dynamic library
Re: g++: -fno-rtti breaks polymorphic catch on dynamic library
- Subject: Re: g++: -fno-rtti breaks polymorphic catch on dynamic library
- From: "Pedro d'Aquino" <email@hidden>
- Date: Fri, 3 Sep 2010 15:59:04 -0300
Stop right there. Exceptions require rtti info to figure out what the types are so compiling with -fno-rtti will break exceptions.
From the man page (the important part is highlighted):
-fno-rtti
Disable generation of information about every class with virtual functions for use by the C++ runtime type identification features (dynamic_cast and typeid). If you don't use those parts of the language, you can save some space by using this flag. Note that exception handling uses the same information, but ***it will generate it as needed***. The dynamic_cast operator can still be used for casts that do not require runtime type information, i.e. casts to "void *" or to unambiguous base classes.
Doesn't this mean gcc makes exceptions work even with -fno-rtti? This does seem to be the case, since every scenario but dynamic libraries work (and even they do in Linux).
On Fri, Sep 3, 2010 at 3:54 PM, Andrew Pinski
<email@hidden> wrote:
On Sep 3, 2010, at 11:33 AM, "Pedro d'Aquino" <
email@hidden> wrote:
Hello,
This is my first time posting on one of Apple's mailing lists, so please forgive me if I'm in the wrong place. I did look for a gcc-specific mailing list but could not find any.
I'm building a shared library with f-no-rtti. Internally, this library throws 'std:invalid_argument' and catches 'std::exception', but the catch clause is never entered.
Stop right there. Exceptions require rtti info to figure out what the types are so compiling with -fno-rtti will break exceptions.
The following code reproduces the problem (g++ 4.2, Mac OS X 10.6):
// library.cpp: exports f(), compiled with -fno-rtti
#include <stdexcept>
#include <iostream>
extern "C" {
void f() {
try {
throw std::invalid_argument("std::exception handler");
} catch( std::exception& e) {
std::cout << e.what() << "\n";
} catch(...) {
std::cout << "... handler\n";
}
}
}
----------
// main.cpp: the main executable, dynamically loads the library
#include <dlfcn.h>
typedef void(*fPtr)();
int main() {
void* handle = dlopen( "./libexception_problem.dylib", RTLD_LAZY );
fPtr p_f = reinterpret_cast<fPtr>( dlsym( handle, "f" ) );
p_f();
}
----------
Output:
MacBook-Pro:teste pfranco$ # works fine with rtti
MacBook-Pro:teste pfranco$ g++ -c library.cpp && g++ -shared -o libexception_problem.dylib library.o && g++ main.cpp -o main && ./main
std::exception handler
MacBook-Pro:teste pfranco$ # breaks with -fno-rtti
MacBook-Pro:teste pfranco$ g++ -c -fno-rtti library.cpp && g++ -shared -o libexception_problem.dylib library.o && g++ -fno-rtti main.cpp -o main && ./main
... handler
MacBook-Pro:teste pfranco$ #-no_dead_strip_inits_and_terms doesn't change anything
MacBook-Pro:teste pfranco$ g++ -c -no_dead_strip_inits_and_terms -fno-rtti library.cpp && g++ -no_dead_strip_inits_and_terms -shared -o libexception_problem.dylib library.o && g++ -fno-rtti -no_dead_strip_inits_and_terms main.cpp -o main && ./main
... handler
MacBook-Pro:teste pfranco$ # linking against the shared library works, but this isn't always an option
MacBook-Pro:teste pfranco$ g++ -c -fno-rtti library.cpp && g++ -shared -o libexception_problem.dylib library.o && g++ -fno-rtti main.cpp -o main -L. -lexception_problem && ./main
std::exception handler
----------
This only happens if the code that throws is in a shared library, and only if the caught type is a base class of the actual exception - catch(std::invalid_argument&) works fine, std::logic_error& doesn't.
Interestingly, this doesn't happen on Linux (g++-4.4), even when running the exact same commands.
Questions:
1. Is this a bug, undefined behavior or by design?
2. How could I make it work, short of linking against the library?
Thanks a lot.
Pedro d'Aquino
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden