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. (was: Re: [PATCH+DOC] Print registers not saved in the frame as "<not saved>", instead of "<optimized out>".)
- From: Mark Kettenis <mark dot kettenis at xs4all dot nl>
- To: palves at redhat dot com
- Cc: gdb-patches at sourceware dot org, eliz at gnu dot org, mark dot kettenis at xs4all dot nl, aburgess at broadcom dot com
- Date: Fri, 20 Sep 2013 14:27:42 +0200 (CEST)
- Subject: Re: [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>".)
- 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>
> Date: Thu, 19 Sep 2013 20:15:20 +0100
> From: Pedro Alves <palves@redhat.com>
>
> On 09/19/2013 05:58 PM, Pedro Alves wrote:
>
> > Now, GDB itself could just assume that call-clobbered registers
> > are always <not saved> in frames other than the innermost, but
> > that'll be not very user friendly, I think.
> >
> > Perhaps... we should completely toss out this patch, and go
> > the other way around. When printing registers of an outer
> > frame, ignore DW_CFA_undefined, and read the registers
> > from the inner frame anyway... IOW, define the values of
> > call-clobbered registers in outer frames as "the values the
> > registers would have if the inner frame returned _now_".
> > Mark, what do you think?
> > (I didn't try implementing that, but I think that'll just
> > mean ignoring the optimized_out flag when dumping registers
> > (but not when printing variables marked as living in "optimized
> > out" registers).
> >
>
> 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. See with the gdb.dwarf/dw2-op-out-param.exp
> test:
>
> Breakpoint 2, 0x000000000040058f in breakpt ()
> (gdb) up
> #1 0x00000000004005a2 in int_param_single_reg_loc (operand0=<optimized out>, operand1=-2401054115373400575, operand2=<optimized out>)
> (gdb) info registers
> rax 0x323d7b35b0 215779849648
> rbx 0xdeadbe00deadbe01 -2401054115373400575
> rcx <optimized out>
> rdx 0xdeadbe04deadbe05 -2401054098193531387
> rsi <optimized out>
> rdi <optimized out>
> rbp 0x0 0x0
> rsp 0x7fffffffda20 0x7fffffffda20
> r8 0x323d7b1f40 215779843904
> r9 0x323d00f310 215771837200
> r10 0x7fffffffd890 140737488345232
> r11 0x323d421640 215776106048
> r12 0x400430 4195376
> r13 0x7fffffffdb10 140737488345872
> r14 0x0 0
> r15 0x0 0
> rip 0x4005a2 0x4005a2 <int_param_single_reg_loc+10>
> eflags 0x202 [ IF ]
> cs 0x33 51
> ss 0x2b 43
> ds 0x0 0
> es 0x0 0
> fs 0x0 0
> gs 0x0 0
>
> 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.
>
> 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.
>
> After the patch, we get:
>
> #0 0x000000000040058f in breakpt ()
> (gdb) info registers
> rax 0x323d7b35b0 215779849648
> rbx 0xdeadbe00deadbe01 -2401054115373400575
> rcx 0xdeadbe02deadbe03 -2401054106783465981
> rdx 0xdeadbe04deadbe05 -2401054098193531387
> rsi 0xdeadbe06deadbe07 -2401054089603596793
> rdi 0xdeadbe08deadbe09 -2401054081013662199
> rbp 0x0 0x0
> rsp 0x7fffffffda18 0x7fffffffda18
> r8 0x323d7b1f40 215779843904
> r9 0x323d00f310 215771837200
> r10 0x7fffffffd890 140737488345232
> r11 0x323d421640 215776106048
> r12 0x400430 4195376
> r13 0x7fffffffdb10 140737488345872
> r14 0x0 0
> r15 0x0 0
> rip 0x40058f 0x40058f <breakpt>
> eflags 0x202 [ IF ]
> cs 0x33 51
> ss 0x2b 43
> ds 0x0 0
> es 0x0 0
> fs 0x0 0
> gs 0x0 0
> (gdb) up
> #1 0x00000000004005a2 in int_param_single_reg_loc (operand0=<optimized out>, operand1=-2401054115373400575, operand2=<optimized out>)
> (gdb) info registers
> rax 0x323d7b35b0 215779849648
> rbx 0xdeadbe00deadbe01 -2401054115373400575
> rcx 0xdeadbe02deadbe03 -2401054106783465981
> rdx 0xdeadbe04deadbe05 -2401054098193531387
> rsi 0xdeadbe06deadbe07 -2401054089603596793
> rdi 0xdeadbe08deadbe09 -2401054081013662199
> rbp 0x0 0x0
> rsp 0x7fffffffda20 0x7fffffffda20
> r8 0x323d7b1f40 215779843904
> r9 0x323d00f310 215771837200
> r10 0x7fffffffd890 140737488345232
> r11 0x323d421640 215776106048
> r12 0x400430 4195376
> r13 0x7fffffffdb10 140737488345872
> r14 0x0 0
> r15 0x0 0
> rip 0x4005a2 0x4005a2 <int_param_single_reg_loc+10>
> eflags 0x202 [ IF ]
> cs 0x33 51
> ss 0x2b 43
> ds 0x0 0
> es 0x0 0
> fs 0x0 0
> gs 0x0 0
> (gdb)
>
> Which is what you'd get with a newer GCC. And, it's exactly what you
> get today if your force a return from frame #1, even with such an old
> binary, and _unpatched_ GDB:
>
> (gdb) return
> Make breakpt return now? (y or n) y
> #0 0x00000000004005a2 in int_param_single_reg_loc (operand0=-2401054106783465981, operand1=-2401054115373400575,
> operand2=-2401054089603596793)
> (gdb) info registers
> rax 0x323d7b35b0 215779849648
> rbx 0xdeadbe00deadbe01 -2401054115373400575
> rcx 0xdeadbe02deadbe03 -2401054106783465981
> rdx 0xdeadbe04deadbe05 -2401054098193531387
> rsi 0xdeadbe06deadbe07 -2401054089603596793
> rdi 0xdeadbe08deadbe09 -2401054081013662199
> rbp 0x0 0x0
> rsp 0x7fffffffda20 0x7fffffffda20
> r8 0x323d7b1f40 215779843904
> r9 0x323d00f310 215771837200
> r10 0x7fffffffd890 140737488345232
> r11 0x323d421640 215776106048
> r12 0x400430 4195376
> r13 0x7fffffffdb10 140737488345872
> r14 0x0 0
> r15 0x0 0
> rip 0x4005a2 0x4005a2 <int_param_single_reg_loc+10>
> eflags 0x202 [ IF ]
> cs 0x33 51
> ss 0x2b 43
> ds 0x0 0
> es 0x0 0
> fs 0x0 0
> gs 0x0 0
> (gdb)
>
> This is rule is applied in value_of_register. This is the function
> eval.c uses for evaluating OP_REGISTER (again, $reg, $pc, etc.), and
> related bits. It isn't used for anything else. The patch makes "info
> registers" and the MI equivalent use it too. I think it just makes a
> lot of sense, as this makes it so that when printing machine registers
> ($pc, etc.), we go through a central function.
>
> Note how gdb.mi/mi-reg-undefined.exp and
> gdb.dwarf2/dw2-reg-undefined.exp tests needed adjustment, but not
> gdb.dwarf2/dw2-op-out-param.exp, as that prints an optimized out
> variable, not register.
I strongly disagree with this change. I think it is useful to show
that rgeisters have not been saved. If you want to look at their
value anyway, you can always go down (or up) the stack and chase the
value of the register yourself.
I also think it doesn't make sense for the varobj subsystem to
reimplement bits of the unwinder subsystem.
If newer GCC versions are even less explicit about saving or not
saving registers than older versions, we should probably improve the
_dwarf2_frame_init_reg() implementations to indicate properly which
registers are caller-saved and which registers are callee-saved.
- 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>".)