Exceptionwerfen geht nicht mehr



  • Hi,

    diese Fehlerbox kriege ich, wenn ich versuche, in einer Methode in einem Plugin meiner Engine (dynamisch geladene DLL), eine AGE-Exception zu werfen (mehr dazu unten):
    Hier klicken

    So werfe ich die Exception:

    AGEERROR(DataDirectoryNotFoundException, "The directory " + m_strPath + " does not exist!");
    

    So sieht meine Exceptionklasse aus:

    namespace AGE
    {
    
    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) {} \
    };
    
    // ...
    MAKEEXCEPTIONCLASS(DataException, Exception);
    // ...
    MAKEEXCEPTIONCLASS(DataDirectoryNotFoundException, DataException);
    // ...
    
    #define AGEERROR(Exception, Reason) throw Exception(Reason, __FILE__, __LINE__)
    
    }  // Namespace
    
    Exception::Exception(const String &strReason, const String &strFile, unsigned int nLine) :
    m_strReason(strReason),
    m_strFile(strFile),
    m_nLine(nLine)
    {
    }
    
    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;
    }
    
    String Exception::GetReason() const { return m_strReason; }
    String Exception::GetFile() const { return m_strFile; }
    unsigned int Exception::GetLine() const { return m_nLine; }
    

    Wobei hier höchstens der Konstruktor überhaupt mal aufgerufen wird... 😞

    Hier noch der Assemblercode, falls es was willst:
    [asm] AGEERROR(DataDirectoryNotFoundException, "The directory " + m_strPath + " does not exist!");
    00912235 mov esi,esp
    00912237 push offset string "c:\\dokumente und einstellungen\\c"... (920120h)
    0091223C lea ecx,[ebp-2B8h]
    00912242 call dword ptr [__imp_AGE::String::String (9243E4h)]
    00912248 cmp esi,esp
    0091224A call @ILT+1270(__RTC_CheckEsp) (9114FBh)
    0091224F mov dword ptr [ebp-4],3
    00912256 mov eax,dword ptr [this]
    00912259 add eax,4
    0091225C push eax
    0091225D push offset string "The directory " (92010Ch)
    00912262 lea ecx,[ebp-270h]
    00912268 push ecx
    00912269 call std::operator+<char,std::char_traits<char>,std::allocator<char> > (911375h)
    0091226E add esp,0Ch
    00912271 mov dword ptr [ebp-37Ch],eax
    00912277 mov edx,dword ptr [ebp-37Ch]
    0091227D mov dword ptr [ebp-380h],edx
    00912283 mov byte ptr [ebp-4],4
    00912287 push offset string " does not exist!" (9200F8h)
    0091228C mov eax,dword ptr [ebp-380h]
    00912292 push eax
    00912293 lea ecx,[ebp-24Ch]
    00912299 push ecx
    0091229A call std::operator+<char,std::char_traits<char>,std::allocator<char> > (9111C2h)
    0091229F add esp,0Ch
    009122A2 mov dword ptr [ebp-384h],eax
    009122A8 mov edx,dword ptr [ebp-384h]
    009122AE mov dword ptr [ebp-388h],edx
    009122B4 mov byte ptr [ebp-4],5
    009122B8 mov esi,esp
    009122BA mov eax,dword ptr [ebp-388h]
    009122C0 push eax
    009122C1 lea ecx,[ebp-294h]
    009122C7 call dword ptr [__imp_AGE::String::String (9243E0h)]
    009122CD cmp esi,esp
    009122CF call @ILT+1270(__RTC_CheckEsp) (9114FBh)
    009122D4 mov byte ptr [ebp-4],6
    009122D8 mov ecx,dword ptr [`AGE::FileSystemDataDirectory::Refresh'::`2'::__LINE__Var (923498h)]
    009122DE add ecx,15h
    009122E1 push ecx
    009122E2 lea edx,[ebp-2B8h]
    009122E8 push edx
    009122E9 lea eax,[ebp-294h]
    009122EF push eax
    009122F0 lea ecx,[ebp-2FCh]
    009122F6 call AGE::DataDirectoryNotFoundException::DataDirectoryNotFoundException (911564h)
    009122FB push offset __TI3?AVDataDirectoryNotFoundException@AGE@@ (921834h)
    00912300 lea ecx,[ebp-2FCh]
    00912306 push ecx
    00912307 call @ILT+985(__CxxThrowException@8) (9113DEh) ***** HIER kommt der Fehlerdialog! *****[/asm]

    Die genaue Fehlerzeile in __CxxThrowException@8 kann ich euch auch noch liefern, aber das ist ziemlich viel Code, also sagt grad, wenn ihr es wollt 🙄

    Bitte helft mir!

    ChrisM



  • exception die eine dll verlassen sind potentiell gefährlich: denn jeder compiler hat seine eigene art wie er exceptions umsetzt. wenn du also pech hast, dann vertragen sich die exception der dll nicht mit der der exe.



  • Daran kann es aber aus zwei Gründen nicht liegen:
    1. Die Plugin-DLL und die Engine-DLL, die die Plugin-DLL lädt, sind hier im selben MSVC .net 2003-Arbeitsbereich und werden mit den absolut gleichen Compilereinstellungen und der Multithreaded DLL-Debug-Laufzeit compiliert.
    2. Die Exception müsste erst noch eine Ebene innerhalb des Plugins "fallen", bevor sie zurück zur Engine-DLL kommt, aber wie gesagt tritt der Fehler schon beim ersten Werfen auf!

    ChrisM



  • Sagt mal, darf man in Destruktoren eigentlich Exceptions werfen, ich hab nämlich das komische Gefühl, dass beim Verlassen des Scopes durch eine Exception und das Unwinding des Stacks noch eine Exception vom Destruktor eines Objektes, auf das ein Smart Pointer zeigt, geworfen wird!
    Und meine Fehlermeldung kommt dann einfach daher, weil eine Exception geworfen wird, aber auch nicht auf tiefster Ebene (WinMain()) gefangen wird... 🙂

    Aber darf man in Destruktoren überhaupt Exceptions werfen?

    ChrisM



  • ChrisM schrieb:

    Sagt mal, darf man in Destruktoren eigentlich Exceptions werfen

    technisch gesehen schon, moralisch gesehen nein.

    denn sobald ein dtor ne exception wirft ist man mehr oder weniger im arsch...



  • OK, alle Probleme sind jetzt gelöst. 🙂

    Vielen Dank! 👍

    ChrisM


Anmelden zum Antworten