Kevin O'Connor escreveu:
> On Sun, Jul 01, 2007 at 08:12:33PM +0100, Pedro Alves wrote:
>> Danny Backx wrote:
>>> void Handle(struct _EXCEPTION_RECORD *ExceptionRecord,
>>> void *EstablisherFrame,
>>> struct _CONTEXT *ContextRecord,
>>> struct _DISPATCHER_CONTEXT *DispatcherContext)
>>> {
>>> throw WindowsException(ExceptionRecord, EstablisherFrame,
>>> ContextRecord, DispatcherContext);
>>> }
>> I'm not sure that is safe. You are throwing away from a callback started
>> from the kernel. I think the safest is to tweak the current threads
>> context with GetThreaContext/SetThreadContext to point the pc at a different
>> address like your registered handler, and return
>> EXCEPTION_CONTINUE_EXECUTION. Then, in that handler, you're got the stack
>> setup as if the exception called directly into your handler, and it should be
>> safe to throw a c++ exception. Take another look at cegcc's startup.c for
>> inspiration - It already does something similar.
>
> Is it safe to enter an exception handler using the calling program's
> stack? That is, if you set the pc to a handler and call
> EXCEPTION_CONTINUE_EXECUTION that handler will alter the stack and
> registers of the function that raised the exception. Are we
> guarenteed that this is okay?
>
Of course, just changing the pc is not enough. We have to setup a
new stack frame. Really, you should look at newlib/libc/sys/wince/startup.c:
DWORD* sp = (DWORD*)ContextRecord->Sp;
*--sp = ContextRecord->Pc;
*--sp = ContextRecord->Lr;
*--sp = ContextRecord->Sp;
*--sp = ContextRecord->R12;
*--sp = ContextRecord->R11;
*--sp = ContextRecord->R10;
*--sp = ContextRecord->R9;
*--sp = ContextRecord->R8;
*--sp = ContextRecord->R7;
*--sp = ContextRecord->R6;
*--sp = ContextRecord->R5;
*--sp = ContextRecord->R4;
*--sp = ContextRecord->R3;
*--sp = ContextRecord->R2;
*--sp = ContextRecord->R1;
*--sp = ContextRecord->R0;
*--sp = ContextRecord->Psr;
ContextRecord->Sp = (DWORD) sp;
ContextRecord->Pc = (DWORD) _call_raise_asm;
NestedException = 0;
struct exception_map_t* expt =
get_exception_map_for(ExceptionRecord->ExceptionCode);
if (!expt)
{
printf("Unhandled kernel exception %x\n", ExceptionRecord->ExceptionCode);
exit(-1);
}
printf("%s\n", expt->str);
ContextRecord->R0 = expt->signal;
/* raise(SIGSEGV); */
__eh_continue(ContextRecord);
/* NOT REACHED */
__eh_continue is implemented in asm.
Let me see if I can come up with something in the following days.
Cheers,
Pedro Alves
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Cegcc-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel