"catch" fängt "throw" in verschachtelter funktion nicht auf



  • N'Abend zusammen,
    zunächst mal Entschuldigung für den etwas schwammigen Titel, im Notfall kann ihn ja ein Moderator anpassen 😉

    Jetzt aber zum eigentlichen Problem:
    Ich hab folgendes try...catch Gerüst:

    try {
        eSensor::PassEdge(ww,time,a,r);
    }
    catch( eSensorFinished & e ) {
    

    Und dann hier eSensor::PassEdge (gekürzt):

    void eSensor::PassEdge(const eWall *w,REAL time,REAL a,int){
        if (!w->Massive()){
            return;
        }
    
        // extrapolate the hit time
        REAL hitTime = owned->LastTime() + time * inverseSpeed_;
    
        if (owned && !owned->EdgeIsDangerous(w, hitTime, a))
            return;
    
        ....
    
        throw eSensorFinished();
    }
    

    Der Code compilet wunderbar (unter win8 mit MinGW 4.4.1), crasht aber an dem "throw" und der Debugger sagt mir folgendes:

    #0 006AE6A4	__cxa_throw () (??:??)
    #1 004AFC84	eSensor::PassEdge(this=0x28d9b4, w=0x52c5778, time=2.75361633, a=0.17098549) (C:\Users\Niklas\Desktop\tron\0.4-random-features\src\engine\eSensor.cpp:88)
    

    Ich hab natürlich sofort nachgeschaut, ob ich nicht aus versehen -fexcetions vergessen hatte, was aber nicht der Fall war. Hier die kompletten command-line-arguments:

    mingw32-g++.exe -fexceptions -DWIN32 -D_WINDOWS -D_MBCS -DNO_SOCKLEN_T -DDONTUSEMEMMANAGER  -O2
    

    Das Problem an sich hat mich schon zum grübeln gebracht, dass eigentlich seltsame daran ist aber, dass es auftrat, nachdem ich Änderungen am Code vorgenommen und eigentlich nichts an den Compiler-Einstellungen verändert habe.

    Hoffe ich könnt mir helfen, denn ich selber bin mit meinem Latein am Ende.

    Danke im Voraus 🙂



  • Der Vollständigkeit halber wäre die Implementierung von eSensorFinished noch wichtig.



  • Die hab ich ganz vergessen. Vermutlich weil sie nur so aussieht:

    class eSensorFinished{};
    


  • Ohne kompilierbares Minimalbeispiel und weil mir die Fehlermeldung nichts sagt kann ich nur Vermutung anstellen:

    1.) Wird durch einen destruktor (oder konstruktor) nochmal geworfen?
    2.) Exception specification verwendet? Wird vielleicht bad_exception geworfen?
    3.) Mal catch(...) versucht? Wird es dann korrekt gefangen?



  • KMT schrieb:

    Ohne kompilierbares Minimalbeispiel und weil mir die Fehlermeldung nichts sagt kann ich nur Vermutung anstellen

    Da ist KMT nicht alleine - schau mal in meine Signatur, danach Liefer uns bitte entsprechenden Code, an dem man das Problem nachstellen kann.



  • KMT schrieb:

    Ohne kompilierbares Minimalbeispiel und weil mir die Fehlermeldung nichts sagt kann ich nur Vermutung anstellen:

    Das Problem ist, dass das Programm ein Spiel ist, was heißt du wirst mit 20-60 Zeilen Code (so, wie es in den Forenregeln steht) den Fehler nicht reproduzieren können. Wenn du (oder auch andere) aber den ganzen Sourcecode sehen/selber compilen willst/wollen, so ist er hier zu finden: https://code.launchpad.net/~ai.tron/armagetronad/0.4-queue+timeleft+scoreboard

    KMT schrieb:

    1.) Wird durch einen destruktor (oder konstruktor) nochmal geworfen?

    Nein

    KMT schrieb:

    2.) Exception specification verwendet? Wird vielleicht bad_exception geworfen?

    Nein und Nein

    KMT schrieb:

    3.) Mal catch(...) versucht? Wird es dann korrekt gefangen?

    Ändert leider gar nichts, immernoch das selbe Problem


  • Mod

    kaybee schrieb:

    KMT schrieb:

    Ohne kompilierbares Minimalbeispiel und weil mir die Fehlermeldung nichts sagt kann ich nur Vermutung anstellen:

    Das Problem ist, dass das Programm ein Spiel ist, was heißt du wirst mit 20-60 Zeilen Code (so, wie es in den Forenregeln steht) den Fehler nicht reproduzieren können.

    Super. Dann weißt du doch schon, dass der eigentliche Fehler woanders liegt. Jetzt musst du nur noch rausfinden, wann das Problem weggegangen ist, als du den Code gekürzt hast.



  • Wenn ich mir mal die catch-Blöcke ansehe, wundert mich das nicht weiter:

    catch( eSensorFinished & e )
    {
        if ( DoExtraDetectionStuff() )
            throw;
    }
    

    oder

    catch( eSensorFinished & e )
    {
        [...]
        throw;
    }
    


  • Athar schrieb:

    Wenn ich mir mal die catch-Blöcke ansehe, wundert mich das nicht weiter:
    ....

    Soweit komm ich aber gar nicht, er stürzt davor schon ab.

    SeppJ schrieb:

    kaybee schrieb:

    KMT schrieb:

    Ohne kompilierbares Minimalbeispiel und weil mir die Fehlermeldung nichts sagt kann ich nur Vermutung anstellen:

    Das Problem ist, dass das Programm ein Spiel ist, was heißt du wirst mit 20-60 Zeilen Code (so, wie es in den Forenregeln steht) den Fehler nicht reproduzieren können.

    Super. Dann weißt du doch schon, dass der eigentliche Fehler woanders liegt. Jetzt musst du nur noch rausfinden, wann das Problem weggegangen ist, als du den Code gekürzt hast.

    Ich hab nur gemeint es würde theoretisch nicht gehen. Klar könnte ich jetzt das ganze auf sowas hier reduzieren:

    #include <iostream>
    
    using namespace std;
    
    class eSensorFinished {};
    
    void triggerSensor() {
        throw eSensorFinished();
    }
    
    int main()
    {
        try {
            triggerSensor();
        }
        catch(eSensorFinished &e) {
            cout << "caught eSensorFinished" << "\n";
    
        }
    }
    

    Aber wirklich weiterhelfen würde das nicht, da der Code hier wunderbar läuft, während das Spiel aber abschmiert.



  • kaybee schrieb:

    Soweit komm ich aber gar nicht, er stürzt davor schon ab.

    Wie hast du das festgestellt? Debuggst du etwa mit -O2? Wo ist -g?



  • Athar schrieb:

    kaybee schrieb:

    Soweit komm ich aber gar nicht, er stürzt davor schon ab.

    Wie hast du das festgestellt? Debuggst du etwa mit -O2? Wo ist -g?

    Oh mein Fehler, ich hab die arguments von der Release Version gepostet 🙄 Debug sieht so aus:

    mingw32-g++.exe -fexceptions -DWIN32 -D_CONSOLE -D_MBCS -DEMBEDDED -DDONTUSEMEMMANAGER -DNO_SOCKLEN_T  -g -W -D_DEBUG -DDEBUG
    


  • Ich hab rausgefunden warum mir die "Fehlermeldung" nix sagt. Das ist einfach nur der stacktrace. Und offensichtlich nichtmal der ganze.

    Was heißt denn eigentlich "er stürzt ab"? terminate()? unhandled exception? segfault?

    Davon abgesehen hast du glaube ich denn Sinn eines kompilierbaren Minimalbeispiels nicht ganz verstanden. Wenn du uns Code lieferst der funktioniert, dann werden wir da - Überraschung - auch keinen Fehler finden. Betrifft übrigens auch deinen Eröffnungsbeitrag.
    Genausowenig haben die Leute hier aber Lust - und vorallem Zeit - sich durch tausende Zeilen code durchzuarbeiten.

    Tatsächlich wird es in deinem Projekt ziemlich sicher tausende Zeilen von code geben, die man einfach rausstreichen (bzw auskommentieren) kann, und der Fehler wird immer noch auftreten. In 90% der Fälle findet man dann den Fehler sogar direkt selber.
    Schau dir doch einfach mal den call stack an, und kommentier einfach die funktion calls aus, die nicht im call stack bis zum Fehler drinnen sind. Vielleicht hast du Abhängigkeiten zu Ladefunktion - auskommentieren/hardcoden.
    Ich glaub dir einfach nicht, dass es nicht gehen soll, weil ich (und nebenbei auch andere hier) sowas eben oft genug gemacht haben.



  • Ich hab den Code schon soweit runter kommentiert, dass das Spiel nicht mehr crasht. Und zwar einfach indem ich alle Funktionen die "throw" werfen auskommentiert habe. Insofern weiß ich nicht, wo ich da weitermachen sollen.

    Es ist ja auch Fakt, dass bei anderen Leuten der selbe Code nicht crasht und das verwirrt mich doch sehr



  • Bei dem Namen

    eSensorFinished
    

    für die Exception könnte man glatt denken, Du setzt Exceptions zur Ablaufsteuerung ein, was man aber nicht sollte. Sie sind nicht das geeignete Mittel dafür.



  • Das ist mir bewusst, aber es ist wie gesagt nicht mein Code und ich will ihn auch nicht grundlegend verändern



  • Rebuild-All gemacht?
    Verwenden alle Module den selben Exception-Handling Modus (sjlj vs. Dwarf-2)?
    Wirfst du Exceptions über DLL Grenzen?



  • 1. Ja, mehrmals
    2. Ich benutze MinGW GCC 4.4.1 welches seit Version 3.4 sjlj gar nicht mehr ünterstützt
    3. Nein, die throw Funktion(en) und auch alles was davor kommt, passiert nur im Hauptprogramm selber



  • Vielleicht Funktionsaufrufe über Funktionszeiger oder extern "C" Funktionen? Bzw. schonmal in der MinGW/GCC Doku nachgesehen in welchen Fällen der Compiler davon ausgeht dass nixe geworfen wird?

    Bzw. ... funktioniert alles wenn du das "throw" durch z.B. eine globale Variable + if + return "nachstellst"?
    Mir drängt sich nämlich schön langsam der Verdacht auf dass du Speicher kaputthaust.



  • hustbaer schrieb:

    Bzw. ... funktioniert alles wenn du das "throw" durch z.B. eine globale Variable + if + return "nachstellst"?
    Mir drängt sich nämlich schön langsam der Verdacht auf dass du Speicher kaputthaust.

    Verstehe nicht ganz, was du meinst, vielleicht könntest du es mir etwas genauer erklären 😃

    Ich hab jetzt mal folgendes probiert:

    void testfunction()
    {
        throw eSensorFinished();
    }
    
    void gSensor::PassEdge(const eWall *ww,REAL time,REAL a,int r){
        if (!ww)
            return;
    
        try{
            //eSensor::PassEdge(ww,time,a,r);
            testfunction();
        }
        //catch( eSensorFinished & e )
        catch(...)
        {
        }
    

    und er bleibt jetzt bei testfunktion hängen, liegt also nicht an dem code der in der funktion eSensor::PassEdge vor dem throw steht


Anmelden zum Antworten