[Dwarf-Discuss] Location list entries for caller-saved registers at time of call

Michael Eager eager at eagercon.com
Thu Dec 6 09:19:20 PST 2018


On 12/06/2018 04:40 AM, David Stenberg via Dwarf-Discuss wrote:
> Hi!
> 
> When GDB and LLDB perform virtual unwinding, they subtract one byte
> from the return addresses of the outer frames. This is for example
> necessary when unwinding from a non-returning call that is placed last
> in the function, as the return address then can point to a different
> function. I assume that this is also necessary to get the variables
> that were in scope at the time of the call, and the right location
> expressions for the variables, etc.

As you mention, GDB is trying to insure that the computed return address
is within the scope of the function, so that the function will be
identified correctly.

> As far as I have understood it, GCC utilizes this fact for location
> list entries that are expressed in caller-saved registers, by
> subtracting one from the (exclusive) ending address of the entries.

Similarly, the ending address of a LocList entry could be one beyond
the end of a function, if the address is of a variable allocated at
the end.  Subtracting one insures that the correct function is
identified.

> This means that variables in outer frames that are located in caller-
> saved registers will be printed out as <optimized out> by GDB
Why?

> I have not been able to find anything in the DWARF standard that
> describes this. Is this something that is defined by standard, or is it
> established praxis between GCC and GDB? If the latter, do you know of
> other producers and consumers that behave like this?

No, this is not part of the DWARF specification.

This isn't any shared knowledge between GCC and GDB.  Subtracting
one from the end address to insure that the address is within the
function is simply to accommodate the occasional situation where the
call is the last instruction in the function.

> The reason why I ask this is because Clang/LLVM at the moment ends
> location list entries expressed in caller-saved registers at the first
> instruction after the call. This means that variables in outer frames
> using such location list entries will incorrectly be evaluated using
> the inner-most frame's register values when debugging in GDB.

The DWARF definition of a LocList entry (Sec. 2.6.2) says that the
     "[t]he starting address is the lowest address of the address range
     over which the location is valid. The ending address is the address
     of the first location past the highest address of the address
     range."

GDB frame handling is recursive and can be confusing.  In most cases,
GDB uses the next frame pointer as a handle for evaluating variables
in the current frame.  That does not mean that the evaluation is
using the inner-frame registers.

(From your other email):

Hmm, right. I'm not very familiar with the design philosophy of GDB,
but as far as I have understood it they prefer to rely on producer to
emit such information. In the LLVM bug report [0] I wrote for this I
mentioned using DW_CFA_undefined for caller-saved registers, or at
least for those that it knows are clobbered.

Why?

Neither GCC nor Clang emits CFI for caller-saved registers at the
moment. I have not been successful in finding out why, but my
(uneducated) guess is that, maybe at least one of the reasons, is
debug info size concerns?

Exactly.   Some (most?) producers do not encode ABI requirements in
the CFI, since this would be duplicated in every CFI entry.

DWARF philosophy is not to duplicate information which is defined
by the ABI or other architecture definitions.

-- 
Michael Eager    eager at eagercon.com
1960 Park Blvd., Palo Alto, CA 94306


More information about the Dwarf-Discuss mailing list