Exception wird nicht gefangen



  • Hallo

    Ich habe folgendes Problem:
    Ich lade in mein Hauptprogramm eine dynamische Library und beziehe ein Objekt "account", welches in dieser Library erstellt wird.

    Anschliessend rufe ich eine Methode dieses Objekts auf und fange mögliche Exceptions.

    try {
        account->initialize();
    } catch (EException& e) {
        throw e; // (1)
    } catch (std::runtime_error& e) {
        throw e; // (2)
    } catch (...) {
        throw e; // (3)
    }
    

    Wenn ich nun in der "initialize"-Methode eine Runtime-Exception werfe

    throw std::runtime_error("test");
    

    dann wird diese wie erwartet in (2) weitergeleitet.

    Weiter habe ich eine Klasse EException erstellt, welche von std::runtime_error erbt und in einer statischen Library liegt. Diese statische Library wird von der Hauptapplikation, wie auch von der dynamischen Library reingelinkt.

    Wenn ich nun in "initialize" eine EException werfe:

    throw EException("test");
    

    dann wird diese Exception in (3) weitergeleitet. Wieso?!?

    Kennt jemand dieses Problem und weiss, wie man dies lösen kann?

    Besten Dank



  • OT: Du solltest (re)throwund nicht throw e verwenden.
    http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.9



  • Du solltest in den catchs immer konstante Referenzen behandeln:

    catch (std::runtime_error const& err)
    {
        throw;
    }
    


  • Biolunar schrieb:

    Du solltest in den catchs immer konstante Referenzen behandeln:

    catch (std::runtime_error const& err)
    {
        throw;
    }
    

    Ist nicht zwingend und manchmal nicht sinnvoll (z.B. wenn zusätzliche Information hinzugefügt werden soll).
    Simon



  • Aber du kompilierst schon alles mit dem selben Compiler/selben Einstellungen?



  • Welcher Compiler? Exceptions über Programm/Library-Grenzen hinweg waren schon immer ein unangenehmes Thema...



  • /rant/ schrieb:

    Welcher Compiler? Exceptions über Programm/Library-Grenzen hinweg waren schon immer ein unangenehmes Thema...

    Ich verwende gcc 4.4.1 und ja, ich kompiliere alles mit der selben Umgebung und Einstellungen.

    Const kann ich nicht machen, da ich in der Tat noch weitere Informationen an die Exception anhänge. Zudem besteht das Problem auch mit Verwendung von const.



  • Hmm.
    Der Standard schreibt nichts vor, also ist das eher ein Verhalten von GCC.

    Schau mal hier:
    http://stackoverflow.com/questions/2424836/exceptions-are-not-caught-in-gcc-program

    Also mal noch die Option

    -shared-libgcc
    

    anhängen.



  • Unter der Annahme, dass du beim Kompilieren der Bibliothek -fvisibility=hidden benutzt (was bei Bibliotheken durchaus üblich ist): Du musst die gesamte Exception-Klasse mit __attribute__(visibility("default")) versehen, sonst wird die vtable nicht exportiert, und beim Fangen der Exception schlägt das Nachschlagen der typeinfo fehl.

    Das ganze ist hier beschrieben: http://gcc.gnu.org/wiki/Visibility (Unterpunkt "Problems with C++ exceptions")



  • drakon schrieb:

    Hmm.
    Der Standard schreibt nichts vor, also ist das eher ein Verhalten von GCC.

    Schau mal hier:
    http://stackoverflow.com/questions/2424836/exceptions-are-not-caught-in-gcc-program

    Also mal noch die Option

    -shared-libgcc
    

    anhängen.

    Vielen Dank für diesen Tipp!
    Es funktioniert nun schon etwas besser. Wenn ich eine "EException" werfe, dann lande ich immerhin schon in (2).
    Aber eben leider immer noch nicht in (1)...

    Hab mir das mit der Visibility mal Durchgelesen und in "EException" eingebaut. Dies ändert jedoch nichts (weder am Verhalten, noch in der Ausgabe von "nm -C -D <library>.so" wie ganz unten auf der Seite deines Links angegeben).



  • Du landest mit der EException im Handler für std::runtime_error ?!

    WTF?
    Hmm. Ich würde mal sagen, dass du den Fehler am ehesten mit solchen Flags beheben kannst. Der Code und dein Vorgehen ist imo schon korrekt.
    Vielleich findest du noch mehr Compilerspezifisches dazu.

    Ich bin so drauf gestossen:
    http://www.google.ch/search?q=gcc+exception+not+caught&ie=utf-8&oe=utf-8&aq=t&client=firefox-a&rlz=1R1GGGL_de___CH343

    Da hat es noch eine Menge anderer Themen mit dem gleichen/ähnlichen Problem.



  • Vielen vielen Dank an alle!!

    Hab diesen Fehler endlich beheben können.
    Als erstes hat das Compilerflag "-shared-libgcc" erste Erfolge verzeichnet.
    Nach etwas googeln hab ich auch noch erfahren, dass Exceptions über Librarygrenzen hinaus nur funktioniert, wenn man keine Methoden-Implementationen in den Exception-Header Dateien hat.
    Sobald ich diese in die Source-Dateien verschoben habe, hat es funktioniert!

    Hab zur Sicherheit auch noch das Visibility-Flag gesetzt.

    Nochmals allen vielen Dank. Hab wirklich lange an diesem Fehler gesessen. 🙂


Anmelden zum Antworten