How is an exception transferred to find a handler?

前端 未结 2 1106
[愿得一人]
[愿得一人] 2021-01-24 06:13

When an exception is thrown stack unwinding is initiated until handling code is encountered, but I am a little unclear on the mechanics of the whole process.

1 - where i

相关标签:
2条回答
  • 2021-01-24 06:18

    These are all implementation details, to be decided during the (non-trivial) process of designing an exception handling mechanism. I can only give a sketch of how one might (or might not) choose to implement this.

    If you want a detailed description of one implementation, you could read the specification for the Itanium ABI used by GCC and other popular compilers.

    1 - The exception object is stored in an unspecified place, which must last until the exception has been handled. Pointers or references are passed around within the exception handling code like any other variable, before being passed to the handler (if it takes a reference) by some mechanism similar to passing a function argument.

    2 - There are two common approaches: a static data structure mapping the program location to information about the stack frame; or a dynamic stack-like data structure containing information about active handlers and non-trivial stack objects that need destroying.

    In the first case, on throwing it will look at that information to see if there are any local objects to destroy, and any local handlers; if not, it will find the function return address on the local stack frame and apply the same process to the calling function's stack frame until a handler is found. Once the handler is found, the CPU registers are updated to refer to that stack frame, and the program can jump to the handler's code.

    In the second case it will pop entries from the stack structure, using them to tell it how to destroy stack objects, until it finds a suitable handler. Once the handler is found, and all unwound stack objects destroyed, it can use longjmp or a similar mechanism to jump to the handler.

    Other approaches are possible.

    3 - The exception handling code will use some kind of data structure to identify a type, allowing it to compare the type being thrown with the type for a handler. This is somewhat complicated by inheritance; the test can't be a simple comparison. I don't know the details for any particular implementation.

    0 讨论(0)
  • 2021-01-24 06:37

    Source: How do exceptions work (behind the scenes) in c++ (I read the assembly and answered the questions by what I understood)

    Question 1#:

    movl    $1, (%esp)
    call    __cxa_allocate_exception
    movl    $_ZN11MyExceptionD1Ev, 8(%esp)
    movl    $_ZTI11MyException, 4(%esp)
    

    _ZTI11MyException is the exception. It looks as if it has it's own allocation not in the stack and it places the pointer in register named eax.

    Question 2#:

    .LFE9:
    .size   _Z20my_catching_functionv, .-_Z20my_catching_functionv
    .section    .gcc_except_table,"a",@progbits
    .align 4
    

    It looks like table that is stored in static data in the program. So it can know where it can catch. There was nothing about how objects destruct themself after unwinding frames so this is from Visual Studio: (The link at the top is from Linux)

            MyClass s, s2, s3, s4;
     mov         dword ptr [ebp-4],3  
            try {
                {
                    MyClass s, s2, s3, s4;
     mov         byte ptr [ebp-4],7  
                }
    

    It looks like it saves the number of objects to destroy. For example when it finishes:

    call        MyClass::~MyClass (0DC1163h)
    mov         dword ptr [ebp-4],0FFFFFFFFh
    

    0FFFFFFFFh means nothing's to destruct. If I find something about how it actually finds and destroyes them I will add here.

    Question 3#:

    As in the previous question, you see there's table for it, it can know whatever it's in the right function.

    0 讨论(0)
提交回复
热议问题