This is the mail archive of the
gdb@sources.redhat.com
mailing list for the GDB project.
Re: dwarf-frame.c question
- From: Jim Blandy <jimb at redhat dot com>
- To: Andrew Cagney <ac131313 at redhat dot com>
- Cc: Mark Kettenis <kettenis at chello dot nl>, mludvig at suse dot cz, gdb at sources dot redhat dot com, Alexandre Oliva <aoliva at redhat dot com>
- Date: 02 Jun 2003 19:03:56 -0500
- Subject: Re: dwarf-frame.c question
- References: <3ED381CB.5050207@suse.cz><200305291544.h4TFi7aL031832@elgar.kettenis.dyndns.org><3ED66564.1020506@redhat.com><200305292222.h4TMMmGm000694@elgar.kettenis.dyndns.org><3ED693F5.9040108@redhat.com> <vt2ptm09nz9.fsf@zenia.red-bean.com><3ED7BFD1.7060902@redhat.com>
Andrew Cagney <ac131313@redhat.com> writes:
> > Andrew Cagney <ac131313@redhat.com> writes:
> >
> >> One idea (the origins of which are unknown) is for the compiler to
> >> generate CFI info containing no addresses and have GDB look for that
> >> dependant on the PC address being obtained using return or resume
> >> (sigtramp, sentinel).
> > I don't understand this. Could you explain the idea in more detail?
>
> A similar technique to the line number information where there are two
> line number entries for the start of function so that GDB can find the
> end of the function prologue given:
>
> int foo (int i) { int j = i * i; return j; }
>
> In this case there would be two CFI entries covering the code at "1:"
> (assuming its possible):
>
> > foo ()
> > {
> > if (i)
> > abort (with, lots, of parameters)
> > do; normal; stuff;
> > }
> > it can be turned into:
> > branch !i, 1:
> > push with
> > push lots
> > push of
> > push parameters
> > call abort
> > 1:
> > do
> > normal
> > stuff
>
> - [1:, 1:): describing the lost return instruction
> - [1:, end-of-function) describing the real code
>
> GDB could pick 'n' choose.
Okay --- thanks for that explanation.
We've already added some DW_CFA_GNU_ opcodes to the CFI spec; we could
solve the problem more unambiguously by introducing something like
DW_CFA_GNU_unwind_from_noreturn:
<rationale italics>
In some cases, the compiler may determine that a particular
subroutine will never return. It may not be possible in general
to unwind activation frames for calls to such functions: the
compiler is free to generate code which throws away information
the debugger would need to do so, since the compiler knows that
information will never be used by the program itself. But in
practice there will often be sufficient information to unwind the
frame; since developers will often want to look at the
preceding stack frames, compilers are encouraged to emit call
frame information for such subroutines anyway.
However, unwinding the frame of a call to a subroutine which will
never return yields a processor state which will never actually
occur in the running program. Since the compiler is free to place
arbitrary code (or no code at all) immediately after a call
instruction which it knows will never return, the unwound return
address may point to an instruction whose unwinding rules are
different from those needed after the call has "returned". In
this case, the debugger needs two distinct sets of unwinding rules
for the same code address: one to apply when unwinding again after
unwinding the call which will never return, and one to apply when
the code location was reached via other means.
The debugger can distinguish these two cases by considering the
next younger frame: if it is a frame for an ordinary function,
then the first set of rules applies; but if it is a frame for a
signal handler, or a frame synthesized by the debugger itself (in
order to call a function in the program, for example), or if there
is no younger frame, then the second set of rules applies.
</rationale italics>
The DW_CFA_GNU_unwind_from_noreturn instruction indicates that the
current set of rules applies only when the current location was
reached by unwinding a frame called by this one, not when it was
reached from elsewhere in the subroutine.
The DW_CFA_GNU_unwind_from_noreturn instruction also creates a new
table row whose location value is the same as this one; this
latter row applies when the given location was reached from
elsewhere in the same subroutine.