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 klickenSo 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