EXCEPTION_DISPOSITION exceptionHandler(struct _EXCEPTION_RECORD* pExceptionRec, void* pEstablisherFrame, struct _CONTEXT* pContextRecord, void* pDispatcherContext)
{
	fflush(stderr);
	fflush(stdout);
	static int running=0;

	if(running)
		exit(1);

	running=1;

	if(mysaveFunction) mysaveFunction();

        if(myFatalFunction) myFatalFunction ("Crash","Press ok to build crash info");

	void* currentProcessId = GetCurrentProcess();

	SymInitialize(currentProcessId, NULL, TRUE);

	dumpExceptionInfo(currentProcessId, pExceptionRec, pContextRecord);
	fflush(stdout);
	dumpBackTrace(currentProcessId);

	SymCleanup(currentProcessId);

	exit(1);
}
Example #2
0
void WINAPI EXC_RtlRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context )
{
    PEXCEPTION_FRAME    frame, dispatch, nested_frame;
    EXCEPTION_RECORD    newrec;
    EXCEPTION_POINTERS  epointers;
    DWORD res, c;

    if (((unsigned long)(rec->ExceptionAddress) & 0xffff0000) == 0xdead0000)
        ERR("possibly COM stub exception at %p\n", rec->ExceptionAddress);
    TRACE( "code=%lx flags=%lx addr=%p\n", rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress );
    for (c=0; c<rec->NumberParameters; c++) TRACE(" info[%ld]=%08lx\n", c, rec->ExceptionInformation[c]);
    if (rec->ExceptionCode == EXCEPTION_WINE_STUB) TRACE(" stub=%s\n", (char*)rec->ExceptionInformation[1]);
    /* TRACE( " backtrace %s\n", debugstack(10, context) ); */

    if (send_debug_event( rec, TRUE, context ) == DBG_CONTINUE) return;  /* continue execution */

    SIGNAL_Unblock(); /* we may be in a signal handler, and exception handlers may jump out */

    frame = NtCurrentTeb()->except;
    nested_frame = NULL;
    while (frame != (PEXCEPTION_FRAME)0xFFFFFFFF)
    {
        /* Check frame address */
        if (((void*)frame < NtCurrentTeb()->stack_low) ||
            ((void*)(frame+1) > NtCurrentTeb()->stack_top) ||
            (int)frame & 3)
        {
            WARN ("Marking as invalid. Frame: %p, stack_low: %p, Frame+1: %p, stack_top: %p, frame&3: %d\n",
                  (void *)frame, NtCurrentTeb ()->stack_low, (void *)(frame+1),
                  NtCurrentTeb ()->stack_top, (int)frame & 3);
            rec->ExceptionFlags |= EH_STACK_INVALID;
            break;
        }

        /* Call handler */
        res = EXC_CallHandler( rec, frame, context, &dispatch, frame->Handler, EXC_RaiseHandler );
        if (frame == nested_frame)
        {
            /* no longer nested */
            nested_frame = NULL;
            rec->ExceptionFlags &= ~EH_NESTED_CALL;
        }

        switch(res)
        {
        case ExceptionContinueExecution:
            if (!(rec->ExceptionFlags & EH_NONCONTINUABLE)) return;
            newrec.ExceptionCode    = STATUS_NONCONTINUABLE_EXCEPTION;
            newrec.ExceptionFlags   = EH_NONCONTINUABLE;
            newrec.ExceptionRecord  = rec;
            newrec.NumberParameters = 0;
            RtlRaiseException( &newrec );  /* never returns */
            break;
        case ExceptionContinueSearch:
            break;
        case ExceptionNestedException:
            if (nested_frame < dispatch) nested_frame = dispatch;
            rec->ExceptionFlags |= EH_NESTED_CALL;
            break;
        case ExceptionCollidedUnwind:
            /* Check for having gotten into an infinite exception loop due to
             a busted exception frame somewhere */
            if (rec->ExceptionCode == STATUS_INVALID_DISPOSITION)
                EXC_DefaultHandling (rec, context);
       default:
            newrec.ExceptionCode    = STATUS_INVALID_DISPOSITION;
            newrec.ExceptionFlags   = EH_NONCONTINUABLE;
            newrec.ExceptionRecord  = rec;
            newrec.NumberParameters = 0;


            /* dump the crash report here since the next RtlRaiseException()
               call will never return and the exception info from this point on will
               be clobbered.  */
            epointers.ContextRecord = context;
            epointers.ExceptionRecord = rec;

            if (!dumpExceptionInfo(&epointers, NTDLL_CRASHREPORTFILENAME, NTDLL_MINIDUMPFILENAME))
                ERR("ERROR-> could not dump the crash report\n");

            RtlRaiseException( &newrec );  /* never returns */
            break;
        }
        frame = frame->Prev;
    }
    EXC_DefaultHandling( rec, context );
}