[Gc] workaround for C++ exceptions problem
pizlo at mac.com
Wed Jan 25 13:20:40 PST 2006
On Jan 25, 2006, at 1:10 AM, skaller wrote:
> On Tue, 2006-01-24 at 22:58 -0500, Filip Pizlo wrote:
>> On Jan 24, 2006, at 10:43 PM, skaller wrote:
>>> No. at the point you mention NO exceptions are 'in flight'.
>>> BOTH of them have already 'landed'.
>> I figured it wasn't the right terminology to use, but assumed
>> everyone would know what I meant. The point is that the exception
>> objects and their types are being managed by the C++ runtime.
> That isn't clear though: when an exception is caught,
> who knows what happens to it?
You mean, it isn't clear what happens to an exception while you're in
the catch block? The spec may not know (or maybe it does, I haven't
read up on that part), but GCC knows. :-) And if we can make it work
for GCC it'll be a big deal.
What is sure is that when you catch an exception, there won't
necessarily be a pointer to it from the stack, and even if there is,
the GC can't really do much with such a pointer if it points at
something returned from the system malloc.
>>> In flight means 'taken off but not landed', that is:
>>> thrown but not caught.
>> Thanks for the clarification.
> Lol .. that was just my definition :)
> Lets just look at Hans proposal to copy the 'current'
> exception object on the assumption it is unique: I think
> my point is that can't work.
> What I expect to happen is explained as follows. Multiple
> exceptions in flight arise because unwinding is recursive.
> During unwinding .. which pops the stack .. it is necessary
> to destroy the stacked objects before actually popping the
> stack pointer.
What do you mean by "what I expect to happen"? Is this what you
expect that the C++ runtime does Right Now, or is this the New And
Improved version that's supposed to be GC friendly? What are you
If you are still using your definition of 'in flight', then I'm not
sure how far we're going to get. If the exception is caught but
still managed by the runtime ('not in flight' by your terminology),
then we still have a problem.
For the purpose of interactions between the GC and C++ exceptions,
the state of an exception when it is caught is no different than when
it is 'in flight'. In both cases, the exception lives in some place
that the GC cannot see.
> The process of destroying those objects may itself use
> local variables, that is, it can push data onto the stack.
> So inside this context, the code acts quite normally,
> AS IF there were no exception in flight. In particular,
> you can throw an exception and it will fire off just fine,
> and start unwinding the stack.
What do you mean 'the code acts quite normally'?
> If you catch it inside that context .. all continues exactly
> as normal. There is a problem if the exception keeps propagating
> outside the context of the routine destroying the stack,
> so there has to be a check at this point somehow.
What continues as normal? What does normal mean?
> Now in particular, the original exception is probably
> pushed onto the stack, and the slot for holding the
> current exception is cleared, so that any new exception
> can be stored there .. that is, the system is in the
> state that looks like no exception is in flight.
If I understand what you are saying, the original exception 'slot'
that you refer to is actually not cleared, it's kept around. That's
what GCC does anyway.
> In particular that pushed exception is now ON the stack
> and so the GC can find it without it being a root.
Why would it be on the stack? It isn't as far as I know.
> Note: I'm guessing -- other possibilities exist,
> such as not clearing that location until a new throw
> actually happens. Or, it may use some other
> storage as the stack (could be useful if the error
> was due to 'out of stack space' .. :)
> It seems to me there is even worse to come if you try
> to track the exception state.
> OTOH your original suggestion seems better to me!
> By hooking the allocation, it matters not whether
> or when the deallocation occurs -- as long as the hook catches
> all allocations and deallocations and passes them on
> to the gc.
> Even this may not work! As I understand it these are
> root objects which are scanable but not collectable.
> So what happens if somehow the pointer is stored
> somewhere reachable and lost by the EH mechanism?
> I have no idea if this can happen -- probably NOT
> in ISO C++, but it is hard to be sure without one's
> brain throwing a double fault :)
What pointer? All you've got is an exception object (which may have
pointers, or may be a pointer) and it has to end up somewhere. The
allocation routines determine where it ends up.
More information about the Gc