From: Aurelien Regat-Barrel on 20 Nov 2006 05:13 Hi, I am writting an exception filter for my app that displays a message box and kills the app. The problem is that it does nothing if the exception is a stack overflow, because some stack space is needed to execute my error handling code... I tried to use _resetstkoflw() but it doesn't help. Is there a way to recover some stack space in order to execute my handler before killing the app? I am thinking about: - modifying ESP by hand (risky) - unblocking a thread in my handler, and execute my error handling code in that thread Do you have better idea ? Thanks. -- Aur?lien Regat-Barrel
From: Jochen Kalmbach [MVP] on 20 Nov 2006 05:23 Hallo Aurelien! > - modifying ESP by hand (risky) static LONG __stdcall CrashHandlerExceptionFilter(EXCEPTION_POINTERS* pExPtrs) { if (pExPtrs->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) { static char MyStack[1024*128]; // be sure that we have enought space... // it assumes that DS and SS are the same!!! (this is the case for Win32) // change the stack only if the selectors are the same (this is the case for Win32) //__asm push offset MyStack[1024*128]; //__asm pop esp; __asm mov eax,offset MyStack[1024*128]; __asm mov esp,eax; } // TODO: ... }
From: Aurelien Regat-Barrel on 20 Nov 2006 08:11 Jochen Kalmbach [MVP] a ?crit : > Hallo Aurelien! Hello, >> - modifying ESP by hand (risky) > > > static LONG __stdcall CrashHandlerExceptionFilter(EXCEPTION_POINTERS* > pExPtrs) > { > if (pExPtrs->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) > { > static char MyStack[1024*128]; // be sure that we have enought > space... > // it assumes that DS and SS are the same!!! (this is the case for > Win32) > // change the stack only if the selectors are the same (this is the > case for Win32) > //__asm push offset MyStack[1024*128]; > //__asm pop esp; > __asm mov eax,offset MyStack[1024*128]; > __asm mov esp,eax; > } > > // TODO: ... > } Thanks. I guess I can no longer use pExPtrs after modifying esp, nor any local variable even if declared after the change? -- Aur?lien Regat-Barrel
From: Jochen Kalmbach [MVP] on 20 Nov 2006 08:23 Hi Aurelien! >> static LONG __stdcall CrashHandlerExceptionFilter(EXCEPTION_POINTERS* >> pExPtrs) >> { >> if (pExPtrs->ExceptionRecord->ExceptionCode == >> EXCEPTION_STACK_OVERFLOW) >> { >> static char MyStack[1024*128]; // be sure that we have enought >> space... >> // it assumes that DS and SS are the same!!! (this is the case for >> Win32) >> // change the stack only if the selectors are the same (this is >> the case for Win32) >> //__asm push offset MyStack[1024*128]; >> //__asm pop esp; >> __asm mov eax,offset MyStack[1024*128]; >> __asm mov esp,eax; >> } >> >> // TODO: ... >> } > > Thanks. I guess I can no longer use pExPtrs after modifying esp, nor any > local variable even if declared after the change? Local variables and paramaters are addressed via "ebp". And this points to the "correct" value (because I have not changed "ebp". But you should not use any local variables, because this increases the (unchanged) stack! By the way: There is *no* reliable way to catch unhandled exceptions in-process! The only reliable way is to let your ptogram run under a debugger... Greetings Jochen
From: Aurelien Regat-Barrel on 20 Nov 2006 10:06
Jochen Kalmbach [MVP] a ?crit : > Local variables and paramaters are addressed via "ebp". And this points > to the "correct" value (because I have not changed "ebp". > > But you should not use any local variables, because this increases the > (unchanged) stack! > > By the way: There is *no* reliable way to catch unhandled exceptions > in-process! > The only reliable way is to let your ptogram run under a debugger... You might guessed that I am writing a "graceful" exit of my app for the end user version. The goal is to display a "sorry for this" message and log some infos of the crash. I found a way to get the name of the unhandled expception type with VC++. I am not yet sure what I will do with it, but I give it here, it might help someone (provided "as is"): #include <typeinfo> #define EXCEPTION_MSC 0xE06d7363 // '?msc' if ( ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_MSC && ExceptionInfo->ExceptionRecord->NumberParameters == 3 ) { ULONG_PTR param0 = ExceptionInfo->ExceptionRecord->ExceptionInformation[ 0 ]; ULONG_PTR param1 = ExceptionInfo->ExceptionRecord->ExceptionInformation[ 1 ]; ULONG_PTR param2 = ExceptionInfo->ExceptionRecord->ExceptionInformation[ 2 ]; DWORD magicNumber = param0; if ( magicNumber == 0x19930520 ) // 1999/05/20 { void *pExceptionObject = reinterpret_cast<void*>( param1 ); const _s__ThrowInfo * pThrowInfo = reinterpret_cast<_s__ThrowInfo *>( param2 ); _TypeDescriptor * pType = pThrowInfo->pCatchableTypeArray->arrayOfCatchableTypes[ 0 ]->pType; type_info *info = reinterpret_cast<type_info*>( pType ); std::cout << "Microsoft C++ Exception: " << info->name() << '\n'; } } It's ugly, but it works :-) -- Aur?lien Regat-Barrel |