Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Changeset 485

Show
Ignore:
Timestamp:
01/08/11 15:45:57 (14 years ago)
Author:
Don Clugston
Message:

Added exception frame handling for debugging.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/rt/deh.d

    r482 r485  
    190190} 
    191191 
    192192/+ 
    193193 
    194194Implementation of Structured Exception Handling in DMD-Windows 
    195195 
    196196Every function which uses exception handling (a 'frame') has a thunk created 
    197197for it. This thunk is the 'language-specific handler'. 
    198198The thunks are created in the DMD backend, in nteh_framehandler() in nteh.c. 
    199199These thunks are of the form: 
    200       MOV     EAX,&scope_table 
     200      MOV     EAX, &scope_table 
    201201      JMP     __d_framehandler 
    202202FS:[0] contains a singly linked list of all active handlers (they'll all be 
    203203thunks). The list is created on the stack.  
    204204At the end of this list is _except_handler3, a function in the DMC library. 
    205 Its signature is: 
     205It may be unnecessary. I think it is included for compatibility with MSVC 
     206exceptions? The function below is useful for debugging. 
    206207 
    207208extern(C) 
    208209EXCEPTION_DISPOSITION _except_handler3(EXCEPTION_RECORD *eRecord, 
    209210    DEstablisherFrame * frame,CONTEXT *context,void *dispatchercontext); 
    210211 
    211 It may be unnecessary. I think it is included for compatibility with MSVC 
    212 exceptions? 
     212// Walk the exception handler chain 
     213void printHandlerChain() 
     214
     215    DEstablisherFrame *head; 
     216    asm 
     217    { 
     218        mov EAX, FS:[0]; 
     219        mov head, EAX; 
     220    } 
     221    while (head && head != cast(DEstablisherFrame *)~0) 
     222    { 
     223        printf("%p %p ", head, head.handler); 
     224        if (head.handler == &unwindCollisionExceptionHandler) 
     225             printf("UnwindCollisionHandler\n"); 
     226        else if (head.handler == &_except_handler3) 
     227            printf("excepthandler3\n"); 
     228        else 
     229        { 
     230            ubyte *hnd = cast(ubyte *)head.handler; 
     231            if (hnd[0] == 0xB8 && hnd[5]==0xE9) // mov EAX, xxx; jmp yyy; 
     232            { 
     233                int adr = *cast(int *)(hnd+6); 
     234                printf("thunk: frametable=%x adr=%x ", *cast(int *)(hnd+1), hnd + adr+10); 
     235                if (cast(void *)(hnd + adr + 10) == &_d_framehandler) 
     236                    printf("dframehandler\n"); 
     237                else printf("\n"); 
     238            } else printf("(unknown)\n"); 
     239        } 
     240        head = head.prev; 
     241    } 
     242
    213243 
    214244Documentation of Windows SEH is hard to find. Here is a brief explanation: 
    215245 
    216246When an exception is raised, the OS calls each handler in the FS:[0] list in 
    217247turn, looking for a catch block. It continues moving down the list, as long as 
    218248each handler indicates that it has not caught the exception. When a handler is 
    219249ready to catch the exception, it calls the OS function RtlUnwind. 
    220250This calls each function in the FS:[0] list again, this time indicating that it 
    221251is a 'unwind' call. All of the intervening finally blocks are run at this time. 
    222252The complicated case is a CollidedException, which happens when a finally block