Extrem mysteriöser Assertfehler



  • Hi,

    ich dreh hier langsam noch durch, ich bin schon zig mal mit dem Debugger durchgerattert, aber das einzigste, was ich sehe, ist, dass die Assertion irgendwo in den Tiefen der Laufzeitbibliothek ausgelöst wird, weil ich delete angeblich einen ungültigen Zeiger übergeben haben soll.

    Hier mein Code:

    // Techdemo.exe, das Startprojekt, benutzt die Engine
    try
    {
    // Hier wird eine Exception ausgelöst
    }
    catch (Exception &Exception)
    {
        MessageBox(NULL, Exception.GetErrorString(), "Error", MB_ICONERROR | MB_OK);  // Wird angezeigt
        MessageBox(NULL, "Die Techdemo wird wegen eines Fehlers beendet.", "Fehler", MB_ICONERROR | MB_OK);  // Hierhin kommt die Programmanzeige schon gar nicht mehr!
    }
    
    // Engine.dll, die Engine
    class Exception
    {
    public:
        AGEAPI Exception(const String &strReason, const String &strFile, unsigned int nLine);
    
        AGEAPI String GetErrorString(void) const;
    
        AGEAPI String GetReason(void) const;
        AGEAPI String GetFile(void) const;
        AGEAPI unsigned int GetLine(void) const;
    
    protected:
        String m_strReason, m_strFile;
        unsigned int m_nLine;
    };
    
    #define MAKEEXCEPTIONCLASS(Name, BaseClass) \
    class Name : public BaseClass \
    { \
    public: \
        Name(const String &strReason, const String &strFile, unsigned int nLine) : \
        BaseClass(strReason, strFile, nLine) {} \
    };
    
    // Erstellung einer Hierarchie mittels MAKEEXCEPTIONCLASS()-Makro
    
    String Exception::GetErrorString() const
    {
        String strError = String("Error '") + m_strReason + "' occured in " + m_strFile +
            " in line " + String(static_cast<int>(m_nLine)) + "!\n\nDisplaying callstack: ";
    
        CallStackEnumerator Enumerator;
        const char *pchFunctionName;
        while(pchFunctionName = Enumerator.Enumerate())
            strError += String(pchFunctionName) + " -> ";
    
        strError += "Exception thrown!";
    
        return strError;
    }
    
    class String : public std::string
    {
    public:
        AGEAPI String(void);
        AGEAPI String(const std::string &strString);
        AGEAPI String(const char *pString);
        AGEAPI String(int nInteger);
        AGEAPI String(float fFloat);
    
        virtual ~String(void) {}
    
        AGEAPI String operator +(const char *pChar) const;
        AGEAPI String operator +(const String &String) const;
    
        AGEAPI operator const char*(void) const;
    
    private:
        static String IntToString(int nInteger);
        static String FloatToString(float fFloat);
    };
    
    String String::operator +(const char *pChar) const
    {
        return static_cast<std::string>(*this) + pChar;
    }
    
    String String::operator +(const String &String) const
    {
        return static_cast<std::string>(*this) + static_cast<std::string>(String);
    }
    

    Der Callstackenumerator funktioniert einwandfrei (zumindest kommt der Fehler im Assemblercode nach dem call für die erste MessageBox(), aber vor dem Code für die zweite!)

    Falls es jemand braucht:

    00411D69 call dword ptr [__imp__MessageBoxA@16 (41E760h)]
    00411D6F cmp esi,esp
    00411D71 call @ILT+770(__RTC_CheckEsp) (411307h)
    00411D76 mov byte ptr [ebp-4],0Fh
    00411D7A lea ecx,[ebp-20Ch]
    00411D80 call AGE::String::~String (4112C6h) -> FEHLER <-
    MessageBox(NULL, "Die Techdemo wird wegen eines Fehlers beendet.", "Fehler", MB_ICONERROR | MB_OK);
    00411D85 mov esi,esp
    00411D87 push 10h
    00411D89 push offset string "Fehler" (41B170h)
    00411D8E push offset string "Die Techdemo wird wegen eines Fe"... (41B138h)
    00411D93 push 0
    00411D95 call dword ptr [__imp__MessageBoxA@16 (41E760h)]

    EDIT: Codetags

    ChrisM

    PS: Ja, beide Projekte verwenden die Multithreaded DLL-Laufzeit, daran liegt es also garantiert nicht!

    PPS: Obwohl es daran ja nicht liegen dürfte, hier auch noch der passende Code für das Stack Tracing:

    std::vector<const char*> g_StackTrace;
    
    void AGE::TraceFunction(const char *pchFunctionName)
    {
        g_StackTrace.push_back(pchFunctionName);
    }
    
    CallStackEnumerator::CallStackEnumerator(void) :
    m_Iterator(g_StackTrace.end() - 1)
    {}
    
    CallStackEnumerator::~CallStackEnumerator(void)
    {
        g_StackTrace.clear();
    }
    
    const char *CallStackEnumerator::Enumerate(void)
    {
        if (m_Iterator < g_StackTrace.begin())
            return 0;
    
        return *m_Iterator--;
    }
    
    #ifdef _DEBUG
    namespace AGE { AGEAPI void TraceFunction(const char*); }
    #define GUARD(Function) static const char *AGEDbg_FunctionName = #Function; try {
    #define UNGUARD } catch(...) { MessageBox(NULL, AGEDbg_FunctionName, "Exceptionwurf jetzt in:", MB_ICONINFORMATION | MB_OK); AGE::TraceFunction(AGEDbg_FunctionName); throw; }
    #endif
    

    ChrisM

    [ Dieser Beitrag wurde am 02.07.2003 um 18:51 Uhr von ChrisM editiert. ]



  • schreib am besten alles nochmal :p



  • EDIT: Codetags geändert, warum ist C++ nicht mehr standardmäßig für die Farben eingestellt, wenn man nur code ohne type= schreibt?

    Bitte helft mir, oder wollt ihr, dass ich durchdreh 😃

    ChrisM

    [ Dieser Beitrag wurde am 02.07.2003 um 18:16 Uhr von ChrisM editiert. ]



  • kannst du dein projekt hochladen? würde gerne mittüfteln.



  • Ist leider 46,8 MB (49.112.116 Bytes) groß 😞

    Ich hab schon versucht, den Fehler zu isolieren, aber das gelingt mir nicht, in meinen Testprojekten geht dann immer wunderbar 😞

    ChrisM



  • aber doch nicht 48 MB quellcode. sind bestimmt alles temporäre dateien 😮 😮

    die sachen aus dem debug und release ordner kann man ja löschen. kann ich mir selbst kompilieren



  • So, hab den Fehler doch noch gefunden, war doch keine Multithreaded DLL-Laufzeit. 😃

    Tja, das kommt davon, wenn man seine Projektdateien so schnell erstellt 😉

    ChrisM


Anmelden zum Antworten