This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH] Always print call-clobbered registers in outer frames.
- From: Pedro Alves <palves at redhat dot com>
- To: Andrew Burgess <aburgess at broadcom dot com>
- Cc: gdb-patches at sourceware dot org, Eli Zaretskii <eliz at gnu dot org>, Mark Kettenis <mark dot kettenis at xs4all dot nl>
- Date: Tue, 24 Sep 2013 13:06:53 +0100
- Subject: Re: [PATCH] Always print call-clobbered registers in outer frames.
- Authentication-results: sourceware.org; auth=none
- References: <5200F55E dot 2050308 at broadcom dot com> <201308061318 dot r76DIMdd016369 at glazunov dot sibelius dot xs4all dot nl> <5200FECF dot 7030304 at broadcom dot com> <201308061541 dot r76FfYQN022875 at glazunov dot sibelius dot xs4all dot nl> <520142D9 dot 4030304 at redhat dot com> <5208E3C8 dot 7060107 at broadcom dot com> <5208E938 dot 3080305 at redhat dot com> <201308122001 dot r7CK1862007934 at glazunov dot sibelius dot xs4all dot nl> <520E7255 dot 7080206 at redhat dot com> <5211F25A dot 5070907 at broadcom dot com> <5228B15F dot 7060108 at redhat dot com> <5228B2D8 dot 7060604 at broadcom dot com> <5237567C dot 8050406 at redhat dot com> <5239B2D8 dot 4030403 at broadcom dot com> <5239CCB3 dot 605 at redhat dot com> <83zjram6sw dot fsf at gnu dot org> <201309182047 dot r8IKlOGA010471 at glazunov dot sibelius dot xs4all dot nl> <83fvt1mems dot fsf at gnu dot org> <523B2D39 dot 8060303 at redhat dot com> <523B4D48 dot 3050206 at redhat dot com> <523C2B6F dot 4000007 at broadcom dot com>
On 09/20/2013 12:03 PM, Andrew Burgess wrote:
> On 19/09/2013 8:15 PM, Pedro Alves wrote:
>> Like this...
>>
>> --------------
>> Subject: [PATCH] Always print call-clobbered registers in outer frames.
>>
>> With older GCCs, when some variable lived on a call-clobbered register
>> just before a call, GCC would mark such register as undefined across
>> the function call, with DW_CFA_undefined. This is interpreted by the
>> debugger as meaning the variable is optimized out at that point. That
>> is, if the user does "up", and tries to print the variable.
>>
>> Newer GCCs stopped doing that. They now just don't emit a location
>> for the variable, resulting in GDB printing "<optimized out>" all the
>> same. (See <https://sourceware.org/ml/gdb-patches/2012-08/msg00787.html>.)
>>
>> The difference is that with binaries produced by those older GCCs, GDB
>> will also print the registers themselves (info registers / p $reg) as
>> "<optimized out>". This is confusing.
>
> I agree with you 100% on this, however, I feel we're merging two
> arguments together here. The reason gdb prints <optimised out> is
> really because values only support 3 states: available, unavailable, and
> optimized-out, we use optimized-out for the DW_CFA_undefined state.
>
> What we really need is a new state, lets call it not-saved, we don't
> necessarily need to have extra state inside the value object to model
> this, we might (as in your original patch) be able to derive this state,
> but this is a state that a register can be in.
Luckily, I already have a patch that does that. :-)
>> This patch makes GDB always follow this rule (which is what the
>> heuristic unwinders usually do by default):
>>
>> The values of call-clobbered registers in the outer frame, if not
>> saved by the caller, are defined as being the values the registers
>> would have if the inner frame was to return immediately.
>
> You're right that most targets seem to follow this rule, which seems odd
> to me, however I think that the rs600, s390, sh, and tic6x targets
> don't, they set the call-clobbered registers to DW_CFA_undefined in
> their dwarf2_frame_set_init_reg functions, this seems much more sensible
> to me, assuming that call-clobbered registers have not been used seems
> .... odd.
Okay. Reading more code, and investigating the history behind it
convinced me that that is indeed the direction GDB was currently
heading.
>
>>
>> The documentation is updated to more clearly explain this.
>>
>> IOW, ignore DW_CFA_undefined _when printing frame registers_, but
>> not when printing variables. This translates to, if value of a frame
>> register, comes out as optimized out (that's what "not saved"
>> lval_register values end up as), fetch it from the next frame.
>
> I really think this is going to confuse users, we're basically saying
> that call-clobbered registers are assumed to never be clobbered .... we
> might get away with this from very shallow call-stacks, but for very
> deep stacks this seems very unlikely, in which case, a user switches to
> some outer stack and does "info registers", how does he know which
> registers gdb has carefully retrieved and are correct, and which are
> just random values fetched from some inner frame?
I had toyed with something like Doug suggested. See my
other reply to Mark.
> My question then is, what makes you believe the inner, possibly
> call-clobbered value is right?
Nothing, of course. It's just a choice -- either assume it's right,
and somehow warn the user it may not be right through some other means;
or, assume it's not right, and hide the value from the user. If
GDB is wrong, the user can still fetch the value, though it'll take
more steps (up+p $reg+down, etc.). It might still be a good idea to
provide an easier way to "flatten" the not-saved registers as
convenience for that, not sure).
(skipping answering some of the other points as I believe I've answered
them in my other reply to Mark).
>> -However, @value{GDBN} must deduce where registers are saved, from the machine
>> -code generated by your compiler. If some registers are not saved, or if
>> -@value{GDBN} is unable to locate the saved registers, the selected stack
>> -frame makes no difference.
>> +Most ABIs reserve some registers as ``scratch'' registers that don't
>> +need to be saved by the caller (a.k.a. caller-saved or call-clobbered
>> +registers). It may therefore not be possible for @value{GDBN} to know
>
> I think here you should say "Most ABIs reserve some registers as
> ``scratch'' registers that don't need to be saved by the callee"
> (callee, not caller).
Indeed.
>
>> +the value a register had before the call (in other words, in the outer
>> +frame), if the register value has since been changed by the callee.
>> +@value{GDBN} tries to deduce where registers are saved, from the debug
>> +info, unwind info, or the machine code generated by your compiler.
>
> I don't think this is correct either, we try to figure out where callee
> saved registers are stored, but these are not the scratch registers, if
> the scratch registers are needed by the caller then the caller will save
> them, but the callee will just go ahead and use them. Similarly the
> DWARF only tells us about callee saved registers. The caller saved
> registers are now not mentioned in the DWARF as gcc has made sure that
> no variables are live in these registers.
Hmm. You're right, but only if you see a sequence/connection between
the sentences. They're different paragraphs -- the second sentence is
mostly preexisting, and I didn't mean to imply the GDB tries to figure
out where caller-saved/scratch registers are. I'll rephrase it (in
this or the <not saved> patch, whatever we end up with. Thanks.
>
>> If
>> +some register is not saved, or if @value{GDBN} is unable to locate the
>> +saved register, @value{GDBN} will assume the register in the outer
>> +frame had the same location and value it has in the inner frame. In
>> +other words, the values of call-clobbered registers in the outer
>> +frame, if not saved by the caller, are defined as being the values the
>> +registers would have if the inner frame was to return immediately.
>> +This is usually harmless, but note however that if you change a
>> +register in the outer frame, you may also be affecting the inner
>> +frame.
>
> I'd just like to pick up on the "harmless" here, I agree that it would
> be "harmless" in the sense that if we did a return in gdb it would be
> harmless; the register is callee clobbered, the caller either does not
> care what is in the register after the call, or has code to restore the
> value that it does care about.
Right, that's what I was thinking. It'd be better to write that out
explicitly.
> From a debugging point of few though, I
> suspect showing the wrong value might be far from harmless,
No sure why.
> and if this
> patch is merged we need to draw attention to the fact that the more
> "outer" the frame it you're looking at, the more likely call-clobbered
> registers are to be wrong.
Blah, what a rat hole. :-P :-)
Please guys, re-confirm to me the direction you prefer seeing
GDB follow, even after my reasoning further explained (I'm okay
with either approach), and I'll update the corresponding patch's
documentation bits with the suggestions you've sent.
--
Pedro Alves
- References:
- [PATCH] Print registers not saved in the frame as "<not saved>", instead of "<optimized out>". (was: Re: [PATCH] Consistent display of "<optimized out>")
- Re: [PATCH] Print registers not saved in the frame as "<not saved>", instead of "<optimized out>".
- Re: [PATCH] Print registers not saved in the frame as "<not saved>", instead of "<optimized out>".
- Re: [PATCH] Print registers not saved in the frame as "<not saved>", instead of "<optimized out>".
- [PATCH+DOC] Print registers not saved in the frame as "<not saved>", instead of "<optimized out>".
- Re: [PATCH+DOC] Print registers not saved in the frame as "<not saved>", instead of "<optimized out>".
- Re: [PATCH+DOC] Print registers not saved in the frame as "<not saved>", instead of "<optimized out>".
- Re: [PATCH+DOC] Print registers not saved in the frame as "<not saved>", instead of "<optimized out>".
- Re: [PATCH+DOC] Print registers not saved in the frame as "<not saved>", instead of "<optimized out>".
- [PATCH] Always print call-clobbered registers in outer frames. (was: Re: [PATCH+DOC] Print registers not saved in the frame as "<not saved>", instead of "<optimized out>".)
- Re: [PATCH] Always print call-clobbered registers in outer frames.