From: Aurelien Regat-Barrel on
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
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
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
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
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