How is the C ++ exception handling runtime implemented?

I am intrigued by how the C ++ exception handling mechanism works. In particular, where is the exception object stored and how does it spread across several areas until it is discovered? Does it persist in any global area?

Since this may be compiler specific, can someone explain this in the context of the g ++ compiler?

+66
c ++ exception error-handling language-implementation
Jan 29 '09 at 7:30 a.m. a.m.
source share
4 answers

Implementations may vary, but there are some basic ideas that arise from the requirements.

The exception object itself is an object created in one function, destroyed in its caller. Therefore, it is usually not possible to create an object on the stack. On the other hand, many exception objects are not very large. Ergo, you can create, for example, a 32-byte buffer and an overflow to heap if you really need a larger exception object.

Regarding the actual transfer of control, there are two strategies. One of them is to write enough information onto the stack to expand the stack. This is basically a list of destructors to run and exception handlers that can catch the exception. When an exception occurs, run the stack executing these destructors until you find the appropriate catch.

The second strategy moves this information to tables outside the stack. Now that an exception is raised, the call stack is used to determine which input areas are entered but not displayed. They are then scanned in static tables to determine where the thrown exception will be handled and which destructors are executed between them. This means that the stack has less exception costs; return addresses are needed anyway. Tables are additional data, but the compiler can put them in a program segment loaded on demand.

+32
Jan 29 '09 at 10:19
source share

This is defined in 15.1. Throwing an exception to the standard.

The cast creates a temporary object.
How memory is allocated for this temporary object is not indicated.

After creating temporary control of the object, the nearest handler in the call stack is passed. unwinding a stack between a throw and a catch point. As the stack is deleted, any stack variables are destroyed in the reverse order of creation.

If the exception is re-thrown, the temporary one is destroyed at the end of the handler where it was caught.

Note. If you catch the link, the link will link to a temporary one. If you catch by value, the temporary object will be copied to the value (and therefore a copy constructor is required).

Advice from S.Meyers (link Catch by const).

try { // do stuff } catch(MyException const& x) { } catch(std::exception const& x) { } 
+18
Jan 29 '09 at 8:28
source share

You can look here for a detailed explanation.

It may also help to take a look at the trick used in simple C to implement some basic exception handling. This implies using setjmp () and longjmp () as follows: the former saves the stack to mark an exception handler (for example, β€œcatch”), while the latter is used to β€œthrow” the value. An β€œabandoned” value is displayed as if it had been returned from the called function. "Try block" ends when setjmp () is called again or when the function returns.

+10
Jan 29 '09 at 7:57
source share

I know this is an old question, but there is a very good summary explaining how the methods used in each of gcc and VC are here: http://www.hexblog.com/wp-content/uploads/2012/06/Recon-2012 -Skochinsky-Compiler-Internals.pdf

+8
22 Aug '12 at 8:29
source share



All Articles