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 Cegcc-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/cegcc-devel