This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Consistent display of "<optimized out>"


On 08/12/2013 09:01 PM, Mark Kettenis wrote:
>> Date: Mon, 12 Aug 2013 14:55:04 +0100
>> From: Pedro Alves <palves@redhat.com>
>>
>> On 08/12/2013 02:31 PM, Andrew Burgess wrote:
>>> On 06/08/2013 7:39 PM, Pedro Alves wrote:
>>>> On 08/06/2013 04:41 PM, Mark Kettenis wrote:
>>>>>> Date: Tue, 6 Aug 2013 14:49:03 +0100
>>>>>> From: "Andrew Burgess" <aburgess@broadcom.com>
>>>>
>>>>>> 3. My understanding was that values lost due to the ABI of a call site
>>>>>> were recorded as optimized out.  For evidence I would present
>>>>>> dwarf2_frame_prev_register, and how DWARF2_FRAME_REG_UNDEFINED is handled.
>>>>>>
>>>>>> For these reasons I believe my patch should still be considered, what do
>>>>>> you think?
>>>>>
>>>>> I think that registers are either available or unavailble.  A register
>>>>> being unavailble implies that a variable that is supposed to live in
>>>>> such a register may have been optimized out.  Whether GDB's pseudo
>>>>> variables that respresent registers are considered unavailable or
>>>>> optimized out in that case is arguable.
>>>>
>>>> I think improving consistency as in Andrew's patch is good.
>>>
>>> Given almost a week has passed with no further feedback I plan to
>>> commit this patch tomorrow unless there's any further discussion to be had.
>>
>> TBC, note my opinion doesn't get to overrule Mark's.  Consensus
>> works much better, and Mark does have deep knowledge of all
>> ABI/pseudo registers/etc. gdb things.
>> That said, Mark, if you still disagree, please counter argue,
>> otherwise, we'll just have to assume you do agree with the
>> rationales and clarifications.
> 
> Can't say I agree.  It simply doesn't make sense for registers to be
> "optimized out".  I guess there are two reasons why GDB can't display
> the contents of a register in a frame:
> 
> 1. The register contents aren't made available by the debugging
>    interface, i.e. ptrace(2) or the remote stub doesn't tell us.
> 
> 2. The register wasn't saved before calling another function.
> 
> I guess after Andrew's chnages 1) would be shown as <unavailable> and
> 2) would become <optimized out>.  But in the latter case something
> like <not saved> would make more sense.
> 
> That said, Pedro, you're pretty much the expert for this area of GDB.
> So If you think Andrew should go ahead with this, feel free to ignore
> me.

This is a tough call.  I do agree that "optimized out" for registers
is a bit confusing.  However, we already do print "<optimized out>" in
other places, such as when printing expressions, and consistency
is good.  If we did add a distinction, I agree with Andrew that it should
be done in a more systematic way.  However, I'm not really sure we need
much machinery.  Wouldn't something like:

void
val_print_optimized_out (const struct value *val, struct ui_file *stream)
{
  if (value_lval_const (val) == lval_register)
    fprintf_filtered (stream, _("<not saved>"));
  else
    fprintf_filtered (stream, _("<optimized out>"));
}

work?  What could be the register value cases that would print
"not saved" that we'd still want to print "optimized out" ?

...

Hmm, I spent a bit playing with this, and here's what I got.  At
first glance, the changes in output all look reasonable to me.

frame_unwind_got_optimized needed a tweak to return an
lval_register value; it's returning not_lval presently.

Pushed here (along with Andrew's patch) for convenience:
 https://github.com/palves/gdb/commits/register_not_saved
 git@github.com:palves/gdb.git register_not_saved

Here's the (trimmed for brevity) diff of the resulting gdb.log between
after Andrew's path and after my patch, of a run of 
gdb.dwarf2/dw2-op-out-param.exp gdb.dwarf2/dw2-reg-undefined.exp
gdb.mi/mi-reg-undefined.exp, the only tests affected.

(Code patch further below.)

~~~~

 (gdb) PASS: gdb.dwarf2/dw2-reg-undefined.exp: Switch to frame 1
 p/x $rax
-$6 = <optimized out>
+$6 = <not saved>
 (gdb) PASS: gdb.dwarf2/dw2-reg-undefined.exp: print $rax in frame 1
 p/x $rbx
-$7 = <optimized out>
+$7 = <not saved>
 (gdb) PASS: gdb.dwarf2/dw2-reg-undefined.exp: print $rbx in frame 1
 p/x $rcx
-$8 = <optimized out>
+$8 = <not saved>
 (gdb) PASS: gdb.dwarf2/dw2-reg-undefined.exp: print $rcx in frame 1
 p/x $r8
 $9 = 0x323d7b1f40
@@ -109,9 +109,9 @@ p/x $r9
 $10 = 0x323d00f310
 (gdb) PASS: gdb.dwarf2/dw2-reg-undefined.exp: print $r9 in frame 1
 info registers rax rbx rcx r8 r9
-rax            <optimized out>
-rbx            <optimized out>
-rcx            <optimized out>
+rax            <not saved>
+rbx            <not saved>
+rcx            <not saved>
 r8             0x323d7b1f40    215779843904
 r9             0x323d00f310    215771837200
 (gdb) PASS: gdb.dwarf2/dw2-reg-undefined.exp: Check values of rax, rbx, rcx, r8, r9 in frame 1
@@ -120,13 +120,13 @@ frame 2
 33       first_frame ();
 (gdb) PASS: gdb.dwarf2/dw2-reg-undefined.exp: Switch to frame 2
 p/x $rax
-$11 = <optimized out>
+$11 = <not saved>
 (gdb) PASS: gdb.dwarf2/dw2-reg-undefined.exp: print $rax in frame 2
 p/x $rbx
-$12 = <optimized out>
+$12 = <not saved>
 (gdb) PASS: gdb.dwarf2/dw2-reg-undefined.exp: print $rbx in frame 2
 p/x $rcx
-$13 = <optimized out>
+$13 = <not saved>
 (gdb) PASS: gdb.dwarf2/dw2-reg-undefined.exp: print $rcx in frame 2
 p/x $r8
 $14 = 0x323d7b1f40
@@ -135,13 +135,13 @@ p/x $r9
 $15 = 0x323d00f310
 (gdb) PASS: gdb.dwarf2/dw2-reg-undefined.exp: print $r9 in frame 2
 info registers rax rbx rcx r8 r9
-rax            <optimized out>
-rbx            <optimized out>
-rcx            <optimized out>
+rax            <not saved>
+rbx            <not saved>
+rcx            <not saved>
 r8             0x323d7b1f40    215779843904
 r9             0x323d00f310    215771837200
 (gdb) PASS: gdb.dwarf2/dw2-reg-undefined.exp: Check values of rax, rbx, rcx, r8, r9 in frame 2


 
 PASS: gdb.mi/mi-reg-undefined.exp: mi runto stop_frame
@@ -247,35 +247,35 @@ Expecting: ^(330-data-list-register-valu
 (gdb) 
 PASS: gdb.mi/mi-reg-undefined.exp: register values, format r, frame 0
 Expecting: ^(221-data-list-register-values --thread 1 --frame 1 x  0 1 2 8 9[
-]+)?(221\^done,register-values=\[{number="0",value="<optimized out>"},{number="1",value="<optimized out>"},{number="2",value="<optimized out>"},{number="8",value="0x[0-9A-Fa-f]+"},{number="9",value="0x[0-9A-Fa-f]+"}\][
+]+)?(221\^done,register-values=\[{number="0",value="<not saved>"},{number="1",value="<not saved>"},{number="2",value="<not saved>"},{number="8",value="0x[0-9A-Fa-f]+"},{number="9",value="0x[0-9A-Fa-f]+"}\][
 ]+[(]gdb[)] 
 [ ]*)
 221-data-list-register-values --thread 1 --frame 1 x  0 1 2 8 9
-221^done,register-values=[{number="0",value="<optimized out>"},{number="1",value="<optimized out>"},{number="2",value="<optimized out>"},{number="8",value="0x323d7b1f40"},{number="9",value="0x323d00f310"}]
+221^done,register-values=[{number="0",value="<not saved>"},{number="1",value="<not saved>"},{number="2",value="<not saved>"},{number="8",value="0x323d7b1f40"},{number="9",value="0x323d00f310"}]
 (gdb) 
 PASS: gdb.mi/mi-reg-undefined.exp: register values, format x, frame 1
 Expecting: ^(331-data-list-register-values --thread 1 --frame 1 r 0 1 2 8 9[
-]+)?(331\^done,register-values=\[{number="0",value="<optimized out>"},{number="1",value="<optimized out>"},{number="2",value="<optimized out>"},{number="8",value="0x[0-9A-Fa-f]+"},{number="9",value="0x[0-9A-Fa-f]+"}\][
+]+)?(331\^done,register-values=\[{number="0",value="<not saved>"},{number="1",value="<not saved>"},{number="2",value="<not saved>"},{number="8",value="0x[0-9A-Fa-f]+"},{number="9",value="0x[0-9A-Fa-f]+"}\][
 ]+[(]gdb[)] 
 [ ]*)
 331-data-list-register-values --thread 1 --frame 1 r 0 1 2 8 9
-331^done,register-values=[{number="0",value="<optimized out>"},{number="1",value="<optimized out>"},{number="2",value="<optimized out>"},{number="8",value="0x000000323d7b1f40"},{number="9",value="0x000000323d00f310"}]
+331^done,register-values=[{number="0",value="<not saved>"},{number="1",value="<not saved>"},{number="2",value="<not saved>"},{number="8",value="0x000000323d7b1f40"},{number="9",value="0x000000323d00f310"}]
 (gdb) 
 PASS: gdb.mi/mi-reg-undefined.exp: register values, format r, frame 1
 Expecting: ^(222-data-list-register-values --thread 1 --frame 2 x  0 1 2 8 9[
-]+)?(222\^done,register-values=\[{number="0",value="<optimized out>"},{number="1",value="<optimized out>"},{number="2",value="<optimized out>"},{number="8",value="0x[0-9A-Fa-f]+"},{number="9",value="0x[0-9A-Fa-f]+"}\][
+]+)?(222\^done,register-values=\[{number="0",value="<not saved>"},{number="1",value="<not saved>"},{number="2",value="<not saved>"},{number="8",value="0x[0-9A-Fa-f]+"},{number="9",value="0x[0-9A-Fa-f]+"}\][
 ]+[(]gdb[)] 
 [ ]*)
 222-data-list-register-values --thread 1 --frame 2 x  0 1 2 8 9
-222^done,register-values=[{number="0",value="<optimized out>"},{number="1",value="<optimized out>"},{number="2",value="<optimized out>"},{number="8",value="0x323d7b1f40"},{number="9",value="0x323d00f310"}]
+222^done,register-values=[{number="0",value="<not saved>"},{number="1",value="<not saved>"},{number="2",value="<not saved>"},{number="8",value="0x323d7b1f40"},{number="9",value="0x323d00f310"}]
 (gdb) 
 PASS: gdb.mi/mi-reg-undefined.exp: register values, format x, frame 2
 Expecting: ^(332-data-list-register-values --thread 1 --frame 2 r 0 1 2 8 9[
-]+)?(332\^done,register-values=\[{number="0",value="<optimized out>"},{number="1",value="<optimized out>"},{number="2",value="<optimized out>"},{number="8",value="0x[0-9A-Fa-f]+"},{number="9",value="0x[0-9A-Fa-f]+"}\][
+]+)?(332\^done,register-values=\[{number="0",value="<not saved>"},{number="1",value="<not saved>"},{number="2",value="<not saved>"},{number="8",value="0x[0-9A-Fa-f]+"},{number="9",value="0x[0-9A-Fa-f]+"}\][
 ]+[(]gdb[)] 
 [ ]*)
 332-data-list-register-values --thread 1 --frame 2 r 0 1 2 8 9
-332^done,register-values=[{number="0",value="<optimized out>"},{number="1",value="<optimized out>"},{number="2",value="<optimized out>"},{number="8",value="0x000000323d7b1f40"},{number="9",value="0x000000323d00f310"}]
+332^done,register-values=[{number="0",value="<not saved>"},{number="1",value="<not saved>"},{number="2",value="<not saved>"},{number="8",value="0x000000323d7b1f40"},{number="9",value="0x000000323d00f310"}]
 (gdb) 
 PASS: gdb.mi/mi-reg-undefined.exp: register values, format r, frame 2
 testcase ../../../src/gdb/testsuite/gdb.mi/mi-reg-undefined.exp completed in 0 seconds
@@ -338,7 +338,7 @@ Breakpoint 2, 0x000000000040058f in brea
 (gdb) PASS: gdb.dwarf2/dw2-op-out-param.exp: continue to breakpoint: Stop in breakpt for test int_param_single_reg_loc
 bt
 #0  0x000000000040058f in breakpt ()
-#1  0x00000000004005a2 in int_param_single_reg_loc (operand0=<optimized out>, operand1=0xdeadbe00deadbe01, operand2=<optimized out>)
+#1  0x00000000004005a2 in int_param_single_reg_loc (operand0=<not saved>, operand1=0xdeadbe00deadbe01, operand2=<not saved>)
 #2  0x0000000000400577 in main ()
 (gdb) PASS: gdb.dwarf2/dw2-op-out-param.exp: Backtrace for test int_param_single_reg_loc
 continue
@@ -348,7 +348,7 @@ Breakpoint 2, 0x000000000040058f in brea
 (gdb) PASS: gdb.dwarf2/dw2-op-out-param.exp: continue to breakpoint: Stop in breakpt for struct_param_single_reg_loc
 bt
 #0  0x000000000040058f in breakpt ()
-#1  0x00000000004005b2 in struct_param_single_reg_loc (operand0=<optimized out>, operand1=<optimized out>, operand2=<optimized out>)
+#1  0x00000000004005b2 in struct_param_single_reg_loc (operand0=<not saved>, operand1=<not saved>, operand2=<not saved>)
 #2  0x000000000040057d in main ()
 (gdb) KFAIL: gdb.dwarf2/dw2-op-out-param.exp: Backtrace for test struct_param_single_reg_loc (PRMS: symtab/14604)
 continue
@@ -371,7 +371,7 @@ bt
 #1  0x00000000004005d2 in int_param_two_reg_pieces (operand0=0xdeadbe05, operand1=0xdeadbe0100000000, operand2=0x0)
 #2  0x0000000000400589 in main ()
 (gdb) KFAIL: gdb.dwarf2/dw2-op-out-param.exp: Backtrace for test int_param_two_reg_pieces (PRMS: symtab/14605)
~~~~

-------
>From 2e7a45e5752bbdd3344b540dd27fafe0faf4e627 Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Fri, 16 Aug 2013 11:31:13 +0100
Subject: [PATCH] WIP: print "optimized out" register values as "<not saved>"
 instead of "optimized out".

---
 gdb/cp-valprint.c                              |  4 ++--
 gdb/frame-unwind.c                             |  2 +-
 gdb/infcmd.c                                   |  2 +-
 gdb/jv-valprint.c                              |  4 ++--
 gdb/p-valprint.c                               |  4 ++--
 gdb/testsuite/gdb.dwarf2/dw2-op-out-param.exp  | 10 +++++-----
 gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.exp |  4 ++--
 gdb/testsuite/gdb.mi/mi-reg-undefined.exp      |  4 ++--
 gdb/valprint.c                                 | 13 ++++++++-----
 gdb/valprint.h                                 |  3 ++-
 gdb/value.c                                    | 23 ++++++++++++++++++++++-
 gdb/value.h                                    |  4 ++++
 12 files changed, 53 insertions(+), 24 deletions(-)

diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index e83d979..1d7147c 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -298,7 +298,7 @@ cp_print_value_fields (struct type *type, struct type *real_type,
 					  TYPE_FIELD_BITPOS (type, i),
 					  TYPE_FIELD_BITSIZE (type, i)))
 		{
-		  val_print_optimized_out (stream);
+		  val_print_optimized_out (val, stream);
 		}
 	      else
 		{
@@ -334,7 +334,7 @@ cp_print_value_fields (struct type *type, struct type *real_type,
 				      _("<error reading variable: %s>"),
 				      ex.message);
 		  else if (v == NULL)
-		    val_print_optimized_out (stream);
+		    val_print_optimized_out (NULL, stream);
 		  else
 		    cp_print_static_field (TYPE_FIELD_TYPE (type, i),
 					   v, stream, recurse + 1,
diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c
index ce2f6da..69c977e 100644
--- a/gdb/frame-unwind.c
+++ b/gdb/frame-unwind.c
@@ -164,7 +164,7 @@ frame_unwind_got_optimized (struct frame_info *frame, int regnum)
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   struct type *reg_type = register_type (gdbarch, regnum);
 
-  return allocate_optimized_out_value (reg_type);
+  return allocate_not_saved_value (reg_type, frame, regnum);
 }
 
 /* Return a value which indicates that FRAME copied REGNUM into
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index f6a5290..76e84c9 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -2035,7 +2035,7 @@ default_print_one_register_info (struct ui_file *file,
     }
   else if (value_optimized_out (val))
     {
-      val_print_optimized_out (file);
+      val_print_optimized_out (val, file);
       fprintf_filtered (file, "\n");
       return;
     }
diff --git a/gdb/jv-valprint.c b/gdb/jv-valprint.c
index 3b90e54..961a8e8 100644
--- a/gdb/jv-valprint.c
+++ b/gdb/jv-valprint.c
@@ -395,7 +395,7 @@ java_print_value_fields (struct type *type, const gdb_byte *valaddr,
 	      else if (!value_bits_valid (val, TYPE_FIELD_BITPOS (type, i),
 					  TYPE_FIELD_BITSIZE (type, i)))
 		{
-		  val_print_optimized_out (stream);
+		  val_print_optimized_out (val, stream);
 		}
 	      else
 		{
@@ -420,7 +420,7 @@ java_print_value_fields (struct type *type, const gdb_byte *valaddr,
 		  struct value *v = value_static_field (type, i);
 
 		  if (v == NULL)
-		    val_print_optimized_out (stream);
+		    val_print_optimized_out (v, stream);
 		  else
 		    {
 		      struct value_print_options opts;
diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c
index 05d4c6f..6e8a408 100644
--- a/gdb/p-valprint.c
+++ b/gdb/p-valprint.c
@@ -629,7 +629,7 @@ pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr,
 	      else if (!value_bits_valid (val, TYPE_FIELD_BITPOS (type, i),
 					  TYPE_FIELD_BITSIZE (type, i)))
 		{
-		  val_print_optimized_out (stream);
+		  val_print_optimized_out (val, stream);
 		}
 	      else
 		{
@@ -657,7 +657,7 @@ pascal_object_print_value_fields (struct type *type, const gdb_byte *valaddr,
 		  v = value_field_bitfield (type, i, valaddr, offset, val);
 
 		  if (v == NULL)
-		    val_print_optimized_out (stream);
+		    val_print_optimized_out (v, stream);
 		  else
 		    pascal_object_print_static_field (v, stream, recurse + 1,
 						      options);
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-op-out-param.exp b/gdb/testsuite/gdb.dwarf2/dw2-op-out-param.exp
index 5e4ca01..fecb0df 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-op-out-param.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-op-out-param.exp
@@ -46,16 +46,16 @@ gdb_test_no_output "set print frame-arguments all"
 
 # (1) int_param_single_reg_loc
 gdb_continue_to_breakpoint "Stop in breakpt for test int_param_single_reg_loc"
-gdb_test "bt" "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?int_param_single_reg_loc \\(operand0=<optimized out>, operand1=0xdeadbe00deadbe01, operand2=<optimized out>\\)\r\n#2  ($hex in )?main \\(\\)" "Backtrace for test int_param_single_reg_loc"
+gdb_test "bt" "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?int_param_single_reg_loc \\(operand0=<not saved>, operand1=0xdeadbe00deadbe01, operand2=<not saved>\\)\r\n#2  ($hex in )?main \\(\\)" "Backtrace for test int_param_single_reg_loc"
 
 # (2) struct_param_single_reg_loc
 gdb_continue_to_breakpoint "Stop in breakpt for struct_param_single_reg_loc"
 set test "Backtrace for test struct_param_single_reg_loc"
 gdb_test_multiple "bt" "$test" {
-    -re "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?struct_param_single_reg_loc \\(operand0={a = 0xdeadbe00deadbe01, b = <optimized out>}, operand1={a = <optimized out>, b = 0xdeadbe04deadbe05}, operand2=<optimized out>\\)\r\n#2  ($hex in )?main \\(\\)\r\n$gdb_prompt $" {
+    -re "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?struct_param_single_reg_loc \\(operand0={a = 0xdeadbe00deadbe01, b = <not saved>}, operand1={a = <not saved>, b = 0xdeadbe04deadbe05}, operand2=<not saved>\\)\r\n#2  ($hex in )?main \\(\\)\r\n$gdb_prompt $" {
 	xpass $test
     }
-    -re "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?struct_param_single_reg_loc \\(operand0=<optimized out>, operand1=<optimized out>, operand2=<optimized out>\\)\r\n#2  ($hex in )?main \\(\\)\r\n$gdb_prompt $" {
+    -re "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?struct_param_single_reg_loc \\(operand0=<not saved>, operand1=<not saved>, operand2=<not saved>\\)\r\n#2  ($hex in )?main \\(\\)\r\n$gdb_prompt $" {
 	kfail "symtab/14604" $test
     }
 }
@@ -64,7 +64,7 @@ gdb_test_multiple "bt" "$test" {
 gdb_continue_to_breakpoint "Stop in breakpt for struct_param_two_reg_pieces"
 set test "Backtrace for test struct_param_two_reg_pieces"
 gdb_test_multiple "bt" "$test" {
-    -re "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?struct_param_two_reg_pieces \\(operand0={a = 0xdeadbe04deadbe05, b = <optimized out>}, operand1={a = <optimized out>, b = 0xdeadbe00deadbe01}, operand2=<optimized out>\\)\r\n#2  ($hex in )?main \\(\\)\r\n$gdb_prompt $" {
+    -re "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?struct_param_two_reg_pieces \\(operand0={a = 0xdeadbe04deadbe05, b = <not saved>}, operand1={a = <not saved>, b = 0xdeadbe00deadbe01}, operand2=<not saved>\\)\r\n#2  ($hex in )?main \\(\\)\r\n$gdb_prompt $" {
 	xpass $test
     }
     -re "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?struct_param_two_reg_pieces \\(operand0=.*, operand1=.*, operand2=.*\\)\r\n#2  ($hex in )?main \\(\\)\r\n$gdb_prompt $" {
@@ -76,7 +76,7 @@ gdb_test_multiple "bt" "$test" {
 gdb_continue_to_breakpoint "Stop in breakpt for int_param_two_reg_pieces"
 set test "Backtrace for test int_param_two_reg_pieces"
 gdb_test_multiple "bt" "$test" {
-    -re "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?int_param_two_reg_pieces \\(operand0=<optimized out>, operand1=<optimized out>, operand2=<optimized out>\\)\r\n#2  ($hex in )?main \\(\\)\r\n$gdb_prompt $" {
+    -re "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?int_param_two_reg_pieces \\(operand0=<not saved>, operand1=<not saved>, operand2=<not saved>\\)\r\n#2  ($hex in )?main \\(\\)\r\n$gdb_prompt $" {
 	xpass $test
     }
     -re "#0  ($hex in )?breakpt \\(\\)\r\n#1  ($hex in )?int_param_two_reg_pieces \\(operand0=.*, operand1=.*, operand2=.*\\)\r\n#2  ($hex in )?main \\(\\)\r\n$gdb_prompt $" {
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.exp b/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.exp
index 4686648..44bf8e9 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.exp
@@ -45,8 +45,8 @@ for {set f 0} {$f < 3} {incr f} {
 	set pattern_r8_r9_print "$hex"
 	set pattern_r8_r9_info "$hex\\s+$decimal"
     } else {
-	set pattern_rax_rbx_rcx_print "<optimized out>"
-	set pattern_rax_rbx_rcx_info "<optimized out>"
+	set pattern_rax_rbx_rcx_print "<not saved>"
+	set pattern_rax_rbx_rcx_info "<not saved>"
 	set pattern_r8_r9_print "$hex"
 	set pattern_r8_r9_info "$hex\\s+$decimal"
     }
diff --git a/gdb/testsuite/gdb.mi/mi-reg-undefined.exp b/gdb/testsuite/gdb.mi/mi-reg-undefined.exp
index 8bcbb21..cb3a716 100644
--- a/gdb/testsuite/gdb.mi/mi-reg-undefined.exp
+++ b/gdb/testsuite/gdb.mi/mi-reg-undefined.exp
@@ -52,13 +52,13 @@ mi_gdb_test "111-stack-list-frames" \
     "111\\^done,stack=\\\[frame=\{level=\"0\",addr=\"$hex\",func=\"stop_frame\",.*\},frame=\{level=\"1\",addr=\"$hex\",func=\"first_frame\",.*\},frame=\{level=\"2\",addr=\"$hex\",func=\"main\",.*\}\\\]" \
     "stack frame listing"
 
-set opt_out_pattern "<optimized out>"
+set not_saved_pattern "<not saved>"
 
 for {set f 0} {$f < 3} {incr f} {
     if {${f} == 0} {
 	set pattern_0_1_2 ${hex}
     } else {
-	set pattern_0_1_2 ${opt_out_pattern}
+	set pattern_0_1_2 ${not_saved_pattern}
     }
 
     mi_gdb_test "22${f}-data-list-register-values --thread 1 --frame ${f} x  0 1 2 8 9" \
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 753ae34..285a7fe 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -314,7 +314,7 @@ valprint_check_validity (struct ui_file *stream,
       if (!value_bits_valid (val, TARGET_CHAR_BIT * embedded_offset,
 			     TARGET_CHAR_BIT * TYPE_LENGTH (type)))
 	{
-	  val_print_optimized_out (stream);
+	  val_print_optimized_out (val, stream);
 	  return 0;
 	}
 
@@ -336,9 +336,12 @@ valprint_check_validity (struct ui_file *stream,
 }
 
 void
-val_print_optimized_out (struct ui_file *stream)
+val_print_optimized_out (const struct value *val, struct ui_file *stream)
 {
-  fprintf_filtered (stream, _("<optimized out>"));
+  if (val != NULL && value_lval_const (val) == lval_register)
+    fprintf_filtered (stream, _("<not saved>"));
+  else
+    fprintf_filtered (stream, _("<optimized out>"));
 }
 
 void
@@ -805,7 +808,7 @@ value_check_printable (struct value *val, struct ui_file *stream,
       if (options->summary && !scalar_type_p (value_type (val)))
 	fprintf_filtered (stream, "...");
       else
-	val_print_optimized_out (stream);
+	val_print_optimized_out (val, stream);
       return 0;
     }
 
@@ -966,7 +969,7 @@ val_print_scalar_formatted (struct type *type,
      printed, because all bits contribute to its representation.  */
   if (!value_bits_valid (val, TARGET_CHAR_BIT * embedded_offset,
 			      TARGET_CHAR_BIT * TYPE_LENGTH (type)))
-    val_print_optimized_out (stream);
+    val_print_optimized_out (val, stream);
   else if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type)))
     val_print_unavailable (stream);
   else
diff --git a/gdb/valprint.h b/gdb/valprint.h
index 2959098..40e2ebb 100644
--- a/gdb/valprint.h
+++ b/gdb/valprint.h
@@ -160,7 +160,8 @@ extern int read_string (CORE_ADDR addr, int len, int width,
 			enum bfd_endian byte_order, gdb_byte **buffer,
 			int *bytes_read);
 
-extern void val_print_optimized_out (struct ui_file *stream);
+extern void val_print_optimized_out (const struct value *val,
+				     struct ui_file *stream);
 
 extern void val_print_unavailable (struct ui_file *stream);
 
diff --git a/gdb/value.c b/gdb/value.c
index 09ab1bb..6032267 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -747,6 +747,22 @@ allocate_optimized_out_value (struct type *type)
   return retval;
 }
 
+/* Allocate a "not saved" value for type TYPE.  */
+
+struct value *
+allocate_not_saved_value (struct type *type,
+			  struct frame_info *frame, int regnum)
+{
+  struct value *retval = allocate_value (type);
+
+  set_value_optimized_out (retval, 1);
+  VALUE_LVAL (retval) = lval_register;
+  VALUE_FRAME_ID (retval) = get_frame_id (frame);
+  VALUE_REGNUM (retval) = regnum;
+
+  return retval;
+}
+
 /* Accessor methods.  */
 
 struct value *
@@ -886,7 +902,12 @@ static void
 require_not_optimized_out (const struct value *value)
 {
   if (value->optimized_out)
-    error (_("value has been optimized out"));
+    {
+      if (value->lval == lval_register)
+	error (_("register has not been saved in frame"));
+      else
+	error (_("value has been optimized out"));
+    }
 }
 
 static void
diff --git a/gdb/value.h b/gdb/value.h
index bef193c..d4463bf 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -243,6 +243,10 @@ extern int valprint_check_validity (struct ui_file *stream, struct type *type,
 
 extern struct value *allocate_optimized_out_value (struct type *type);
 
+extern struct value *allocate_not_saved_value (struct type *type,
+					       struct frame_info *frame,
+					       int regnum);
+
 /* If VALUE is lval_computed, return its lval_funcs structure.  */
 
 extern const struct lval_funcs *value_computed_funcs (const struct value *);
-- 
1.7.11.7



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]