diff options
author | Pedro Alves <palves@redhat.com> | 2013-10-02 16:15:46 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2013-10-02 16:15:46 +0000 |
commit | 901461f8eb407af99c049a381fc985baefce179c (patch) | |
tree | 4edd1b5e7b901476b85e08c214509eeb2be6db64 /gdb/doc | |
parent | b477a5e649150a2ed9c5090b01989e746d65cef5 (diff) | |
download | gdb-901461f8eb407af99c049a381fc985baefce179c.zip gdb-901461f8eb407af99c049a381fc985baefce179c.tar.gz gdb-901461f8eb407af99c049a381fc985baefce179c.tar.bz2 |
Print registers not saved in the frame as "<not saved>" instead of "<optimized out>".
Currently, in some scenarios, GDB prints <optimized out> when printing
outer frame registers. An <optimized out> register is a confusing
concept. What this really means is that the register is
call-clobbered, or IOW, not saved by the callee. This patch makes GDB
say that instead.
Before patch:
(gdb) p/x $rax $1 = <optimized out>
(gdb) info registers rax
rax <optimized out>
After patch:
(gdb) p/x $rax
$1 = <not saved>
(gdb) info registers rax
rax <not saved>
However, if for some reason the debug info describes a variable as
being in such a register (**), we still want to print <optimized out>
when printing the variable. IOW, <not saved> is reserved for
inspecting registers at the machine level. The patch uses
lval_register+optimized_out to encode the not saved registers, and
makes it so that optimized out variables always end up in
!lval_register values.
** See <https://sourceware.org/ml/gdb-patches/2012-08/msg00787.html>.
Current/recent enough GCC doesn't mark variables/arguments as being in
call-clobbered registers in the ranges corresponding to function
calls, while older GCCs did. Newer GCCs will just not say where the
variable is, so GDB will end up realizing the variable is optimized
out.
frame_unwind_got_optimized creates not_lval optimized out registers,
so by default, in most cases, we'll see <optimized out>.
value_of_register is the function eval.c uses for evaluating
OP_REGISTER (again, $pc, etc.), and related bits. It isn't used for
anything else. This function makes sure to return lval_register
values. 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.
We're likely to need a different encoding at some point, if/when we
support partially saved registers. Even then, I think
value_of_register will still be the spot to tag the intention to print
machine register values differently.
value_from_register however may also return optimized out
lval_register values, so at a couple places where we're computing a
variable's location from a dwarf expression, we convert the resulting
value away from lval_register to a regular optimized out value.
Tested on x86_64 Fedora 17
gdb/
2013-10-02 Pedro Alves <palves@redhat.com>
* cp-valprint.c (cp_print_value_fields): Adjust calls to
val_print_optimized_out.
* jv-valprint.c (java_print_value_fields): Likewise.
* p-valprint.c (pascal_object_print_value_fields): Likewise.
* dwarf2loc.c (dwarf2_evaluate_loc_desc_full)
<DWARF_VALUE_REGISTER>: If the register was not saved, return a
new optimized out value.
* findvar.c (address_from_register): Likewise.
* frame.c (put_frame_register): Tweak error string to say the
register was not saved, rather than optimized out.
* infcmd.c (default_print_one_register_info): Adjust call to
val_print_optimized_out. Use value_of_register instead of
get_frame_register_value.
* mi/mi-main.c (output_register): Use value_of_register instead of
get_frame_register_value.
* valprint.c (valprint_check_validity): Likewise.
(val_print_optimized_out): New value parameter. If the value is
lval_register, print <not saved> instead.
(value_check_printable, val_print_scalar_formatted): Adjust calls
to val_print_optimized_out.
* valprint.h (val_print_optimized_out): New value parameter.
* value.c (struct value) <optimized_out>: Extend comment.
(error_value_optimized_out): New function.
(require_not_optimized_out): Use it. Use a different string for
lval_register values.
* value.h (error_value_optimized_out): New declaration.
* NEWS: Mention <not saved>.
gdb/testsuite/
2013-10-02 Pedro Alves <palves@redhat.com>
* gdb.dwarf2/dw2-reg-undefined.exp <pattern_rax_rbx_rcx_print,
pattern_rax_rbx_rcx_info>: Set to "<not saved>".
* gdb.mi/mi-reg-undefined.exp (opt_out_pattern): Delete.
(not_saved_pattern): New.
Replace use of the former with the latter.
gdb/doc/
2013-10-02 Pedro Alves <palves@redhat.com>
* gdb.texinfo (Registers): Expand description of saved registers
in frames. Explain <not saved>.
Diffstat (limited to 'gdb/doc')
-rw-r--r-- | gdb/doc/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/doc/gdb.texinfo | 31 |
2 files changed, 32 insertions, 4 deletions
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index f5a80d3..705af69 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2013-10-02 Pedro Alves <palves@redhat.com> + + * gdb.texinfo (Registers): Expand description of saved registers + in frames. Explain <not saved>. + 2013-09-25 Doug Evans <dje@google.com> * gdb.texinfo (Debugging Output): Document set/show debug symfile. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 07d5068..cf6f7d3 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -10031,10 +10031,33 @@ were exited and their saved registers restored. In order to see the true contents of hardware registers, you must select the innermost frame (with @samp{frame 0}). -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. +@cindex caller-saved registers +@cindex call-clobbered registers +@cindex volatile registers +@cindex <not saved> values +Usually ABIs reserve some registers as not needed to be saved by the +callee (a.k.a.: ``caller-saved'', ``call-clobbered'' or ``volatile'' +registers). It may therefore not be possible for @value{GDBN} to know +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 the inner frame saved +(``callee-saved'') registers, from the debug info, unwind info, or the +machine code generated by your compiler. If some register is not +saved, and @value{GDBN} knows the register is ``caller-saved'' (via +its own knowledge of the ABI, or because the debug/unwind info +explicitly says the register's value is undefined), @value{GDBN} +displays @w{@samp{<not saved>}} as the register's value. With targets +that @value{GDBN} has no knowledge of the register saving convention, +if a register was not saved by the callee, then its value and location +in the outer frame are assumed to be the same of the inner frame. +This is usually harmless, because if the register is call-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. Note, +however, that if you change such a register in the outer frame, you +may also be affecting the inner frame. Also, the more ``outer'' the +frame is you're looking at, the more likely a call-clobbered +register's value is to be wrong, in the sense that it doesn't actually +represent the value the register had just before the call. @node Floating Point Hardware @section Floating Point Hardware |