Wrong wording in 1.3 "Throwing an exception."
Eli Boling
eboling at inprise.com
Thu Oct 5 18:59:54 UTC 2000
I prefer option 1, with the caveat that the runtimes understand that the stack is no
longer reasonable. At this point, the application is going down for sure, so I don't
think
that's unreasonable. It also allows the most flexibility to the runtime. I am *not*
a fan
of having the unwinder call abort at this point, or to having undefined behaviour.
-Eli
Jim Dehnert wrote:
> > From: Christophe de Dinechin <ddd at cup.hp.com>
> >
> > The current wording doesn't match the C++ standard:
> >
> > > If the unwinder encounters an unexpected error during phase 2,
> > > the unwind runtime may have modified the stack, e.g. popped
> > > frames from it, or landing pad code may have caused stack corruption.
> > > As a result, the unwind library probably could not find a return address,
> > > and the caller of _Unwind_RaiseException could make no assumptions about
> > > the state of its stack. Rather than attempt to return, therefore, the unwind
> > > library should use the exception_cleanup entry in the exception,
> > > and then call abort().
> >
> > What C++ mandates in that case is calling terminate(), not abort(), and that's a
> > decision that only the C++ runtime can make (it may be different for other
> > languages).
> >
> > What's more, the justification doesn't apply very well on IA-64. There is
> > only one return address for _RaiseException, and it is not on the stack
> > but in a local register (br0). Therefore, _RaiseException has very good
> > chances of being able to return to the C++ runtime, and from there, we
> > move only downwards in the calls tack (terminate() which typically calls
> > abort() itself).
> >
> > So the paragraph above should indicate that we return _URC_FATAL_PHASE2_ERROR.
>
> Well, I was about ready to do this, when I got worried. I know we
> talked about this last week, and agreed as above, but I'd like to get
> confirmation from more people than were present that we're not opening
> an implementation can of worms.
>
> As Christophe points out, the objection that a return address might be
> hard to find is at least overstated. But the bigger problem is that
> the caller of _Unwind_RaiseException must assume a garbaged stack, and
> likely has garbage in its registers, including GP and an unknown
> stacked register state, which might make it difficult to find
> terminate() to call it. So the problem isn't really difficulty
> for the unwind runtime, but for its caller. This call (to
> _Unwind_RaiseException) will happen in many places in compiled code, so
> I would think that if we're not careful, we could place some nasty, and
> not very useful, constraints on compilers. Who has thought about the
> implications of this, and what do you think?
>
> There are several potential specifications we can make:
>
> 1) Unwinder returns _URC_FATAL_PHASE2_ERROR.
>
> a) Nothing further specified.
> b) Require that caller call terminate() with no further help.
> c) Require that the unwinder also return valid GP for caller
> (and perhaps other registers). (Remember that we've been
> modifying the context during phase 2 unwinding, so this
> probably requires extra work in the unwinder.)
>
> 2) Unwinder calls abort().
>
> 3) Unwinder may do either (1) or (2).
>
> 4) Unwinder behavior is completely undefined.
>
> Biases, anyone?
>
> Jim
>
> - Jim Dehnert dehnert at sgi.com
> (650)933-4272
More information about the cxx-abi-dev
mailing list