Ist Exceptions fangen abhängig von der runtime?
-
Zufällig habe ich heute festgestellt, dass meine exceptions unter Linux kaputt sind.

Meine dynamic library funktioniert unter Windows und Mac tadellos, unter Windows mit MSVC++10 kompiliert, unter Mac mit llvm-gcc 4.2.
Unter Linux kompiliere ich mit gcc 4.5.0 und musste feststellen, dass ein einfachestry { throw 42; } catch (...) { cout << "Exception caught." << endl; }zu einem abort mit folgender Stacktrace in gcc führt:
#0 0xffffe430 in __kernel_vsyscall () #1 0xf7b808df in raise () from /lib/libc.so.6 #2 0xf7b82220 in abort () from /lib/libc.so.6 #3 0x08979678 in __gnu_cxx::__verbose_terminate_handler() () #4 0x08976465 in __cxxabiv1::__terminate(void (*)()) () #5 0x089764a2 in std::terminate() () #6 0x089765da in __cxa_throw ()Meine DLL (bzw .so unter Linux) wird von einem Programm geladen, das nicht meiner Kontrolle unterliegt und daher wahrscheinlich gegen eine andere C++-runtime linkt als meine DLL.
Die Exception überschreitet allerdings die Grenzen meiner DLL nicht! Sie wird in der DLL geworfen und (zumindest unter Windows und Mac) innerhalb der DLL gefangen.
Könnte das trotzdem den beschriebenen Effekt haben?
Gruß,
Philipp
-
Nein. Die Benutzung von std::cout könnte aber zu Problemen führt, wenn deine DLL eine andere libstdc++ erwartet, als sie bekommt.
Spannend wäre zu wissen, was unter __cxa_throw im Stacktrace steht, also wo die Exception geworfen wird und ob das mit der Zeile, in der "throw 42;" steht, übereinstimmt.
-
Hab mal weiter probiert.
Wenn ich im Debug-mode kompiliere (-g -O0), wird die exception gefangen.
Wnn ich Release kompiliere (-O2) kommt terminate. Die Zeilennummer, die angeblich die Exception wirft, ist 0. Aber alle Zeilennummern werden als 0 angezeigt, wenn nicht mit -g kompiliert ist. Der Funktionsname stimmt aber.EDIT: Mit -g -O2 kompiliert: Die Zeilennummer im debugger stimmt. Genau da fliegt die exception. Das nächste im Stacktrace ist dann schon __cxa_throw
-
Funktioniert die Ausgabe, wenn man throw und catch weglässt?
-
Ja, die std::cout Ausgabe als socher funktioinert auch.
Im Debug-build funktioniert auch die Exception.
Aber im -O2 mode geht's kaputt. WTF?
-
@seldon
Bist du sicher dass die C++ Runtime unter Linux nicht irgendwie "geshared" wird? Im Gegensatz zu Windows DLLs kann man bei SOs ja sagen "bitte nur eine Kopie dieser Funktion/Variable"...Und da C++ Exceptions sehrwohl Runtime-Library Support brauchen, könnte das schon ein Problem darstellen.
Andrerseits sollte GCC sich an die Itanium ABI halten. Wobei ich nicht weiss, ob das auch das Exception-Handling mit einschliesst (ist ja ein eigener Teil des ABI Standards)...
-
-fuse-cxa-atexit ist wohl Exception-relevant; das musste man bei älteren gccs noch manuell aktivieren, aber bei neueren (>= 4.2?) soll das automatisch gehen.
-
Das Problem kommt mir bekannt vor, mit dem intel compiler hatte ich das selbe Problem. Ich habe einige PT drauf verschwendet da zu debuggen und im Netz nach Referenzen zu suchen, viel war nicht zu finden. Ein Kollege, der auch einiges an Zeit in den Mist investiert hat, kam auch nicht zu Ergebnissen. Seitdem werden die beiden Sourcen mit dem Handler und dem throw nurnoch mit IIRC -g -O1 übersetzt. Das sollte noch gehen, Problem taucht erst bei O2 auf. Was der Optimizer da mit dem Handler anstellt ist dann ne andere Frage.