public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/2] Fix "info frame" in the outermost frame.
@ 2013-11-29 20:16 Pedro Alves
  2013-11-29 20:20 ` [PATCH 2/2] " Pedro Alves
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Pedro Alves @ 2013-11-29 20:16 UTC (permalink / raw)
  To: gdb-patches

Doing "info frame" in the outermost frame, when that was indicated by
the next frame saying the unwound PC is undefined/not saved, results
in error and incomplete output:

 (gdb) bt
 #0  thread_function0 (arg=0x0) at threads.c:63
 #1  0x00000034cf407d14 in start_thread (arg=0x7ffff7fcb700) at pthread_create.c:309
 #2  0x000000323d4f168d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

 (gdb) frame 2
 #2  0x000000323d4f168d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115
 115             call    *%rax

 (gdb) info frame
 Stack level 2, frame at 0x0:
  rip = 0x323d4f168d in clone (../sysdeps/unix/sysv/linux/x86_64/clone.S:115); saved rip Register 16 was not saved
 (gdb)

This mini-series fixes it.  Afterwards, we get:

 (gdb) info frame
 Stack level 2, frame at 0x0:
  rip = 0x323d4f168d in clone (../sysdeps/unix/sysv/linux/x86_64/clone.S:115); saved rip = <not saved>
  Outermost frame: outermost
  caller of frame at 0x7ffff7fcafc0
  source language asm.
  Arglist at 0x7ffff7fcafb8, args:
  Locals at 0x7ffff7fcafb8, Previous frame's sp is 0x7ffff7fcafc8
 (gdb)

Pedro Alves (2):
  New OPTIMIZED_OUT_ERROR error code.
  Fix "info frame" in the outermost frame.

 gdb/dwarf2loc.c                                    |   7 +-
 gdb/exceptions.h                                   |   4 +
 gdb/frame.c                                        | 111 +++--
 gdb/frame.h                                        |   8 -
 gdb/spu-tdep.c                                     |   5 +-
 gdb/stack.c                                        |  27 +-
 gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.S  | 508 +++++++++++++++++++++
 gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.c  |  36 ++
 .../gdb.dwarf2/dw2-undefined-ret-addr.exp          |  58 +++
 gdb/valops.c                                       |   3 +-
 gdb/valprint.c                                     |   8 +-
 gdb/valprint.h                                     |   3 +
 12 files changed, 712 insertions(+), 66 deletions(-)
 create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.S
 create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.c
 create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.exp

-- 
1.7.11.7

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 2/2] Fix "info frame" in the outermost frame.
  2013-11-29 20:16 [PATCH 0/2] Fix "info frame" in the outermost frame Pedro Alves
@ 2013-11-29 20:20 ` Pedro Alves
  2013-12-02  9:04   ` Yao Qi
  2013-12-08  2:40   ` Yao Qi
  2013-11-29 20:39 ` [PATCH 1/2] New OPTIMIZED_OUT_ERROR error code Pedro Alves
  2013-12-06 20:01 ` [PATCH 0/2] Fix "info frame" in the outermost frame Pedro Alves
  2 siblings, 2 replies; 9+ messages in thread
From: Pedro Alves @ 2013-11-29 20:20 UTC (permalink / raw)
  To: gdb-patches

Doing "info frame" in the outermost frame, when that was indicated by
the next frame saying the unwound PC is undefined/not saved, results
in error and incomplete output:

 (gdb) bt
 #0  thread_function0 (arg=0x0) at threads.c:63
 #1  0x00000034cf407d14 in start_thread (arg=0x7ffff7fcb700) at pthread_create.c:309
 #2  0x000000323d4f168d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115

 (gdb) frame 2
 #2  0x000000323d4f168d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:115
 115             call    *%rax

 (gdb) info frame
 Stack level 2, frame at 0x0:
  rip = 0x323d4f168d in clone (../sysdeps/unix/sysv/linux/x86_64/clone.S:115); saved rip Register 16 was not saved
 (gdb)

Not saved register values are treated as optimized out values
internally throughout.  stack.c:frame_info is handing unvailable
values, but no optimized out ones.  The patch deletes the
frame_unwind_caller_pc_if_available wrapper function and instead lets
errors propagate to frame_info (it's only user).

As frame_unwind_pc now needs to be able to handle and cache two
different error scenarios, the prev_pc.p variable is replaced with an
enumeration.

(FWIW, I looked into making gdbarch_unwind_pc or a variant return
struct value's instead, but it results in lots of boxing and unboxing
for no real gain -- e.g., the mips and arm implementations need to do
computation on the unboxed PC value.  Might as well throw an error on
first attempt to get at invalid contents.)

After the patch, we get:

 (gdb) info frame
 Stack level 2, frame at 0x0:
  rip = 0x323d4f168d in clone (../sysdeps/unix/sysv/linux/x86_64/clone.S:115); saved rip = <not saved>
  Outermost frame: outermost
  caller of frame at 0x7ffff7fcafc0
  source language asm.
  Arglist at 0x7ffff7fcafb8, args:
  Locals at 0x7ffff7fcafb8, Previous frame's sp is 0x7ffff7fcafc8
 (gdb)

A new test is added.  It's based off dw2-reg-undefined.exp, and tweaked to
mark the return address (rip) of "stop_frame" as undefined.

Tested on x86_64 Fedora 17.

gdb/
2013-11-29  Pedro Alves  <palves@redhat.com>

	* frame.c (enum cached_copy_status): New enum.
	(struct frame_info) <prev_pc.p>: Change type to enum
	cached_copy_status.
	(fprint_frame): Handle not saved and unavailable prev_pc values.
	(frame_unwind_pc_if_available): Delete and merge contents into ...
	(frame_unwind_pc): ... here.  Handle OPTIMIZED_OUT_ERROR.  Adjust
	to use enum cached_copy_status.
	(frame_unwind_caller_pc_if_available): Delete.
	(create_new_frame): Adjust.
	* frame.h (frame_unwind_caller_pc_if_available): Delete
	declaration.
	* stack.c (frame_info): Use frame_unwind_caller_pc instead of
	frame_unwind_caller_pc_if_available, and handle
	NOT_AVAILABLE_ERROR and OPTIMIZED_OUT_ERROR errors.
	* valprint.c (val_print_optimized_out): Use val_print_not_saved.
	(val_print_not_saved): New function.
	* valprint.h (val_print_not_saved): Declare.

gdb/testsuite/
2013-11-29  Pedro Alves  <palves@redhat.com>

	* gdb.dwarf2/dw2-undefined-ret-addr.S: New file.
	* gdb.dwarf2/dw2-undefined-ret-addr.c: New file.
	* gdb.dwarf2/dw2-undefined-ret-addr.exp: New file.
---
 gdb/frame.c                                        | 108 +++--
 gdb/frame.h                                        |   8 -
 gdb/stack.c                                        |  27 +-
 gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.S  | 508 +++++++++++++++++++++
 gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.c  |  36 ++
 .../gdb.dwarf2/dw2-undefined-ret-addr.exp          |  58 +++
 gdb/valprint.c                                     |   8 +-
 gdb/valprint.h                                     |   3 +
 8 files changed, 697 insertions(+), 59 deletions(-)
 create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.S
 create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.c
 create mode 100644 gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.exp

diff --git a/gdb/frame.c b/gdb/frame.c
index 69a8059..3e68505 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -50,6 +50,23 @@ static struct frame_info *get_prev_frame_1 (struct frame_info *this_frame);
 static struct frame_info *get_prev_frame_raw (struct frame_info *this_frame);
 static const char *frame_stop_reason_symbol_string (enum unwind_stop_reason reason);
 
+/* Status of some values cached in the frame_info object.  */
+
+enum cached_copy_status
+{
+  /* Value is unknown.  */
+  CC_UNKNOWN,
+
+  /* We have a value.  */
+  CC_VALUE,
+
+  /* Value was not saved.  */
+  CC_NOT_SAVED,
+
+  /* Value is unavailable.  */
+  CC_UNAVAILABLE
+};
+
 /* We keep a cache of stack frames, each of which is a "struct
    frame_info".  The innermost one gets allocated (in
    wait_for_inferior) each time the inferior stops; current_frame
@@ -96,7 +113,7 @@ struct frame_info
 
   /* Cached copy of the previous frame's resume address.  */
   struct {
-    int p;
+    enum cached_copy_status status;
     CORE_ADDR value;
   } prev_pc;
   
@@ -366,10 +383,15 @@ fprint_frame (struct ui_file *file, struct frame_info *fi)
     fprintf_unfiltered (file, "<unknown>");
   fprintf_unfiltered (file, ",");
   fprintf_unfiltered (file, "pc=");
-  if (fi->next != NULL && fi->next->prev_pc.p)
-    fprintf_unfiltered (file, "%s", hex_string (fi->next->prev_pc.value));
-  else
+  if (fi->next == NULL || fi->next->prev_pc.status == CC_UNKNOWN)
     fprintf_unfiltered (file, "<unknown>");
+  else if (fi->next->prev_pc.status == CC_VALUE)
+    fprintf_unfiltered (file, "%s",
+			hex_string (fi->next->prev_pc.value));
+  else if (fi->next->prev_pc.status == CC_NOT_SAVED)
+    val_print_not_saved (file);
+  else if (fi->next->prev_pc.status == CC_UNAVAILABLE)
+    val_print_unavailable (file);
   fprintf_unfiltered (file, ",");
   fprintf_unfiltered (file, "id=");
   if (fi->this_id.p)
@@ -707,10 +729,10 @@ frame_find_by_id (struct frame_id id)
   return NULL;
 }
 
-static int
-frame_unwind_pc_if_available (struct frame_info *this_frame, CORE_ADDR *pc)
+static CORE_ADDR
+frame_unwind_pc (struct frame_info *this_frame)
 {
-  if (!this_frame->prev_pc.p)
+  if (this_frame->prev_pc.status == CC_UNKNOWN)
     {
       if (gdbarch_unwind_pc_p (frame_unwind_arch (this_frame)))
 	{
@@ -740,24 +762,35 @@ frame_unwind_pc_if_available (struct frame_info *this_frame, CORE_ADDR *pc)
 	    {
 	      pc = gdbarch_unwind_pc (prev_gdbarch, this_frame);
 	    }
-	  if (ex.reason < 0 && ex.error == NOT_AVAILABLE_ERROR)
+	  if (ex.reason < 0)
 	    {
-	      this_frame->prev_pc.p = -1;
-
-	      if (frame_debug)
-		fprintf_unfiltered (gdb_stdlog,
-				    "{ frame_unwind_pc (this_frame=%d)"
-				    " -> <unavailable> }\n",
-				    this_frame->level);
-	    }
-	  else if (ex.reason < 0)
-	    {
-	      throw_exception (ex);
+	      if (ex.error == NOT_AVAILABLE_ERROR)
+		{
+		  this_frame->prev_pc.status = CC_UNAVAILABLE;
+
+		  if (frame_debug)
+		    fprintf_unfiltered (gdb_stdlog,
+					"{ frame_unwind_pc (this_frame=%d)"
+					" -> <unavailable> }\n",
+					this_frame->level);
+		}
+	      else if (ex.error == OPTIMIZED_OUT_ERROR)
+		{
+		  this_frame->prev_pc.status = CC_NOT_SAVED;
+
+		  if (frame_debug)
+		    fprintf_unfiltered (gdb_stdlog,
+					"{ frame_unwind_pc (this_frame=%d)"
+					" -> <not saved> }\n",
+					this_frame->level);
+		}
+	      else
+		throw_exception (ex);
 	    }
 	  else
 	    {
 	      this_frame->prev_pc.value = pc;
-	      this_frame->prev_pc.p = 1;
+	      this_frame->prev_pc.status = CC_VALUE;
 	      if (frame_debug)
 		fprintf_unfiltered (gdb_stdlog,
 				    "{ frame_unwind_pc (this_frame=%d) "
@@ -769,27 +802,17 @@ frame_unwind_pc_if_available (struct frame_info *this_frame, CORE_ADDR *pc)
       else
 	internal_error (__FILE__, __LINE__, _("No unwind_pc method"));
     }
-  if (this_frame->prev_pc.p < 0)
-    {
-      *pc = -1;
-      return 0;
-    }
-  else
-    {
-      *pc = this_frame->prev_pc.value;
-      return 1;
-    }
-}
 
-static CORE_ADDR
-frame_unwind_pc (struct frame_info *this_frame)
-{
-  CORE_ADDR pc;
-
-  if (!frame_unwind_pc_if_available (this_frame, &pc))
+  if (this_frame->prev_pc.status == CC_VALUE)
+    return this_frame->prev_pc.value;
+  else if (this_frame->prev_pc.status == CC_UNAVAILABLE)
     throw_error (NOT_AVAILABLE_ERROR, _("PC not available"));
+  else if (this_frame->prev_pc.status == CC_NOT_SAVED)
+    throw_error (OPTIMIZED_OUT_ERROR, _("PC not saved"));
   else
-    return pc;
+    internal_error (__FILE__, __LINE__,
+		    "unexpected prev_pc status: %d",
+		    (int) this_frame->prev_pc.status);
 }
 
 CORE_ADDR
@@ -799,13 +822,6 @@ frame_unwind_caller_pc (struct frame_info *this_frame)
 }
 
 int
-frame_unwind_caller_pc_if_available (struct frame_info *this_frame,
-				     CORE_ADDR *pc)
-{
-  return frame_unwind_pc_if_available (skip_artificial_frames (this_frame), pc);
-}
-
-int
 get_frame_func_if_available (struct frame_info *this_frame, CORE_ADDR *pc)
 {
   struct frame_info *next_frame = this_frame->next;
@@ -1572,7 +1588,7 @@ create_new_frame (CORE_ADDR addr, CORE_ADDR pc)
      very likely to read this, and the corresponding unwinder is
      entitled to rely that the PC doesn't magically change.  */
   fi->next->prev_pc.value = pc;
-  fi->next->prev_pc.p = 1;
+  fi->next->prev_pc.status = CC_VALUE;
 
   /* We currently assume that frame chain's can't cross spaces.  */
   fi->pspace = fi->next->pspace;
diff --git a/gdb/frame.h b/gdb/frame.h
index a5e1629..f8d5bc1 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -548,14 +548,6 @@ extern void put_frame_register_bytes (struct frame_info *frame, int regnum,
 
 extern CORE_ADDR frame_unwind_caller_pc (struct frame_info *frame);
 
-/* Same as frame_unwind_caller_pc, but returns a boolean indication of
-   whether the caller PC is determinable (when the PC is unavailable,
-   it will not be), instead of possibly throwing an error trying to
-   read unavailable memory or registers.  */
-
-extern int frame_unwind_caller_pc_if_available (struct frame_info *this_frame,
-						CORE_ADDR *pc);
-
 /* Discard the specified frame.  Restoring the registers to the state
    of the caller.  */
 extern void frame_pop (struct frame_info *frame);
diff --git a/gdb/stack.c b/gdb/stack.c
index 9a12eb3..848bcb0a 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1408,6 +1408,7 @@ frame_info (char *addr_exp, int from_tty)
   CORE_ADDR frame_pc;
   int frame_pc_p;
   CORE_ADDR caller_pc;
+  volatile struct gdb_exception ex;
 
   fi = parse_frame_specification_1 (addr_exp, "No stack.", &selected_frame_p);
   gdbarch = get_frame_arch (fi);
@@ -1493,11 +1494,29 @@ frame_info (char *addr_exp, int from_tty)
 		     sal.line);
   puts_filtered ("; ");
   wrap_here ("    ");
-  printf_filtered ("saved %s ", pc_regname);
-  if (frame_unwind_caller_pc_if_available (fi, &caller_pc))
-    fputs_filtered (paddress (gdbarch, caller_pc), gdb_stdout);
+  printf_filtered ("saved %s = ", pc_regname);
+
+  TRY_CATCH (ex, RETURN_MASK_ERROR)
+    {
+      caller_pc = frame_unwind_caller_pc (fi);
+    }
+  if (ex.reason < 0)
+    {
+      switch (ex.error)
+	{
+	case NOT_AVAILABLE_ERROR:
+	  val_print_unavailable (gdb_stdout);
+	  break;
+	case OPTIMIZED_OUT_ERROR:
+	  val_print_not_saved (gdb_stdout);
+	  break;
+	default:
+	  fprintf_filtered (gdb_stdout, _("<error: %s>"), ex.message);
+	  break;
+	}
+    }
   else
-    fputs_filtered ("<unavailable>", gdb_stdout);
+    fputs_filtered (paddress (gdbarch, caller_pc), gdb_stdout);
   printf_filtered ("\n");
 
   if (calling_frame_info == NULL)
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.S b/gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.S
new file mode 100644
index 0000000..fc92016
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.S
@@ -0,0 +1,508 @@
+/*
+   Copyright 2013 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+	/* The FDE entry for "stop_frame" in the .debug_frame section has
+	been hand modified to mark the return address (rip) as undefined.
+	Otherwise this file is as generated by gcc 4.7.2 for x86_64.  */
+	.file	"dw2-undefined-ret-addr.c"
+	.text
+.Ltext0:
+	.globl	stop_frame
+	.type	stop_frame, @function
+stop_frame:
+.LFB0:
+	.file 1 "dw2-undefined-ret-addr.c"
+	.loc 1 19 0
+	pushq	%rbp
+.LCFI0:
+	movq	%rsp, %rbp
+.LCFI1:
+	.loc 1 22 0
+	popq	%rbp
+.LCFI2:
+	ret
+.LFE0:
+	.size	stop_frame, .-stop_frame
+	.globl	first_frame
+	.type	first_frame, @function
+first_frame:
+.LFB1:
+	.loc 1 26 0
+	pushq	%rbp
+.LCFI3:
+	movq	%rsp, %rbp
+.LCFI4:
+	.loc 1 27 0
+	movl	$0, %eax
+	call	stop_frame
+	.loc 1 28 0
+	popq	%rbp
+.LCFI5:
+	ret
+.LFE1:
+	.size	first_frame, .-first_frame
+	.globl	main
+	.type	main, @function
+main:
+.LFB2:
+	.loc 1 32 0
+	pushq	%rbp
+.LCFI6:
+	movq	%rsp, %rbp
+.LCFI7:
+	.loc 1 33 0
+	movl	$0, %eax
+	call	first_frame
+	.loc 1 35 0
+	movl	$0, %eax
+	.loc 1 36 0
+	popq	%rbp
+.LCFI8:
+	ret
+.LFE2:
+	.size	main, .-main
+	.section	.debug_frame,"",@progbits
+.Lframe0:
+	.long	.LECIE0-.LSCIE0
+.LSCIE0:
+	.long	0xffffffff
+	.byte	0x1
+	.string	""
+	.uleb128 0x1
+	.sleb128 -8
+	.byte	0x10
+	.byte	0xc
+	.uleb128 0x7
+	.uleb128 0x8
+	.byte	0x90
+	.uleb128 0x1
+	.align 8
+.LECIE0:
+        /* This FDE entry, for stop_frame was modified to mark
+           registers 0 -> 6 as being undefined.  */
+.LSFDE0:
+	.long	.LEFDE0-.LASFDE0
+.LASFDE0:
+	.long	.Lframe0
+	.quad	.LFB0
+	.quad	.LFE0-.LFB0
+
+		/* START OF NEW CONTENT.  */
+        .byte   0x7                     /* DW_CFA_undefined */
+        .uleb128 0x10                   /*   ULEB128 register */
+		/* END OF NEW CONTENT.  */
+
+	.byte	0x4
+	.long	.LCFI0-.LFB0
+	.byte	0xe
+	.uleb128 0x10
+	.byte	0x86
+	.uleb128 0x2
+	.byte	0x4
+	.long	.LCFI1-.LCFI0
+	.byte	0xd
+	.uleb128 0x6
+	.byte	0x4
+	.long	.LCFI2-.LCFI1
+	.byte	0xc
+	.uleb128 0x7
+	.uleb128 0x8
+	.align 8
+.LEFDE0:
+.LSFDE2:
+	.long	.LEFDE2-.LASFDE2
+.LASFDE2:
+	.long	.Lframe0
+	.quad	.LFB1
+	.quad	.LFE1-.LFB1
+	.byte	0x4
+	.long	.LCFI3-.LFB1
+	.byte	0xe
+	.uleb128 0x10
+	.byte	0x86
+	.uleb128 0x2
+	.byte	0x4
+	.long	.LCFI4-.LCFI3
+	.byte	0xd
+	.uleb128 0x6
+	.byte	0x4
+	.long	.LCFI5-.LCFI4
+	.byte	0xc
+	.uleb128 0x7
+	.uleb128 0x8
+	.align 8
+.LEFDE2:
+.LSFDE4:
+	.long	.LEFDE4-.LASFDE4
+.LASFDE4:
+	.long	.Lframe0
+	.quad	.LFB2
+	.quad	.LFE2-.LFB2
+	.byte	0x4
+	.long	.LCFI6-.LFB2
+	.byte	0xe
+	.uleb128 0x10
+	.byte	0x86
+	.uleb128 0x2
+	.byte	0x4
+	.long	.LCFI7-.LCFI6
+	.byte	0xd
+	.uleb128 0x6
+	.byte	0x4
+	.long	.LCFI8-.LCFI7
+	.byte	0xc
+	.uleb128 0x7
+	.uleb128 0x8
+	.align 8
+.LEFDE4:
+	.section	.eh_frame,"a",@progbits
+.Lframe1:
+	.long	.LECIE1-.LSCIE1
+.LSCIE1:
+	.long	0
+	.byte	0x1
+	.string	"zR"
+	.uleb128 0x1
+	.sleb128 -8
+	.byte	0x10
+	.uleb128 0x1
+	.byte	0x3
+	.byte	0xc
+	.uleb128 0x7
+	.uleb128 0x8
+	.byte	0x90
+	.uleb128 0x1
+	.align 8
+.LECIE1:
+.LSFDE7:
+	.long	.LEFDE7-.LASFDE7
+.LASFDE7:
+	.long	.LASFDE7-.Lframe1
+	.long	.LFB0
+	.long	.LFE0-.LFB0
+	.uleb128 0
+	.byte	0x4
+	.long	.LCFI0-.LFB0
+	.byte	0xe
+	.uleb128 0x10
+	.byte	0x86
+	.uleb128 0x2
+	.byte	0x4
+	.long	.LCFI1-.LCFI0
+	.byte	0xd
+	.uleb128 0x6
+	.byte	0x4
+	.long	.LCFI2-.LCFI1
+	.byte	0xc
+	.uleb128 0x7
+	.uleb128 0x8
+	.align 8
+.LEFDE7:
+.LSFDE9:
+	.long	.LEFDE9-.LASFDE9
+.LASFDE9:
+	.long	.LASFDE9-.Lframe1
+	.long	.LFB1
+	.long	.LFE1-.LFB1
+	.uleb128 0
+	.byte	0x4
+	.long	.LCFI3-.LFB1
+	.byte	0xe
+	.uleb128 0x10
+	.byte	0x86
+	.uleb128 0x2
+	.byte	0x4
+	.long	.LCFI4-.LCFI3
+	.byte	0xd
+	.uleb128 0x6
+	.byte	0x4
+	.long	.LCFI5-.LCFI4
+	.byte	0xc
+	.uleb128 0x7
+	.uleb128 0x8
+	.align 8
+.LEFDE9:
+.LSFDE11:
+	.long	.LEFDE11-.LASFDE11
+.LASFDE11:
+	.long	.LASFDE11-.Lframe1
+	.long	.LFB2
+	.long	.LFE2-.LFB2
+	.uleb128 0
+	.byte	0x4
+	.long	.LCFI6-.LFB2
+	.byte	0xe
+	.uleb128 0x10
+	.byte	0x86
+	.uleb128 0x2
+	.byte	0x4
+	.long	.LCFI7-.LCFI6
+	.byte	0xd
+	.uleb128 0x6
+	.byte	0x4
+	.long	.LCFI8-.LCFI7
+	.byte	0xc
+	.uleb128 0x7
+	.uleb128 0x8
+	.align 8
+.LEFDE11:
+	.text
+.Letext0:
+	.section	.debug_info,"",@progbits
+.Ldebug_info0:
+	.long	0x8c
+	.value	0x2
+	.long	.Ldebug_abbrev0
+	.byte	0x8
+	.uleb128 0x1
+	.long	.LASF2
+	.byte	0x1
+	.long	.LASF3
+	.long	.LASF4
+	.quad	.Ltext0
+	.quad	.Letext0
+	.long	.Ldebug_line0
+	.uleb128 0x2
+	.byte	0x1
+	.long	.LASF0
+	.byte	0x1
+	.byte	0x12
+	.quad	.LFB0
+	.quad	.LFE0
+	.long	.LLST0
+	.byte	0x1
+	.uleb128 0x3
+	.byte	0x1
+	.long	.LASF1
+	.byte	0x1
+	.byte	0x19
+	.quad	.LFB1
+	.quad	.LFE1
+	.long	.LLST1
+	.byte	0x1
+	.uleb128 0x4
+	.byte	0x1
+	.long	.LASF5
+	.byte	0x1
+	.byte	0x1f
+	.long	0x88
+	.quad	.LFB2
+	.quad	.LFE2
+	.long	.LLST2
+	.byte	0x1
+	.uleb128 0x5
+	.byte	0x4
+	.byte	0x5
+	.string	"int"
+	.byte	0
+	.section	.debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+	.uleb128 0x1
+	.uleb128 0x11
+	.byte	0x1
+	.uleb128 0x25
+	.uleb128 0xe
+	.uleb128 0x13
+	.uleb128 0xb
+	.uleb128 0x3
+	.uleb128 0xe
+	.uleb128 0x1b
+	.uleb128 0xe
+	.uleb128 0x11
+	.uleb128 0x1
+	.uleb128 0x12
+	.uleb128 0x1
+	.uleb128 0x10
+	.uleb128 0x6
+	.byte	0
+	.byte	0
+	.uleb128 0x2
+	.uleb128 0x2e
+	.byte	0
+	.uleb128 0x3f
+	.uleb128 0xc
+	.uleb128 0x3
+	.uleb128 0xe
+	.uleb128 0x3a
+	.uleb128 0xb
+	.uleb128 0x3b
+	.uleb128 0xb
+	.uleb128 0x11
+	.uleb128 0x1
+	.uleb128 0x12
+	.uleb128 0x1
+	.uleb128 0x40
+	.uleb128 0x6
+	.uleb128 0x2117
+	.uleb128 0xc
+	.byte	0
+	.byte	0
+	.uleb128 0x3
+	.uleb128 0x2e
+	.byte	0
+	.uleb128 0x3f
+	.uleb128 0xc
+	.uleb128 0x3
+	.uleb128 0xe
+	.uleb128 0x3a
+	.uleb128 0xb
+	.uleb128 0x3b
+	.uleb128 0xb
+	.uleb128 0x11
+	.uleb128 0x1
+	.uleb128 0x12
+	.uleb128 0x1
+	.uleb128 0x40
+	.uleb128 0x6
+	.uleb128 0x2116
+	.uleb128 0xc
+	.byte	0
+	.byte	0
+	.uleb128 0x4
+	.uleb128 0x2e
+	.byte	0
+	.uleb128 0x3f
+	.uleb128 0xc
+	.uleb128 0x3
+	.uleb128 0xe
+	.uleb128 0x3a
+	.uleb128 0xb
+	.uleb128 0x3b
+	.uleb128 0xb
+	.uleb128 0x49
+	.uleb128 0x13
+	.uleb128 0x11
+	.uleb128 0x1
+	.uleb128 0x12
+	.uleb128 0x1
+	.uleb128 0x40
+	.uleb128 0x6
+	.uleb128 0x2116
+	.uleb128 0xc
+	.byte	0
+	.byte	0
+	.uleb128 0x5
+	.uleb128 0x24
+	.byte	0
+	.uleb128 0xb
+	.uleb128 0xb
+	.uleb128 0x3e
+	.uleb128 0xb
+	.uleb128 0x3
+	.uleb128 0x8
+	.byte	0
+	.byte	0
+	.byte	0
+	.section	.debug_loc,"",@progbits
+.Ldebug_loc0:
+.LLST0:
+	.quad	.LFB0-.Ltext0
+	.quad	.LCFI0-.Ltext0
+	.value	0x2
+	.byte	0x77
+	.sleb128 8
+	.quad	.LCFI0-.Ltext0
+	.quad	.LCFI1-.Ltext0
+	.value	0x2
+	.byte	0x77
+	.sleb128 16
+	.quad	.LCFI1-.Ltext0
+	.quad	.LCFI2-.Ltext0
+	.value	0x2
+	.byte	0x76
+	.sleb128 16
+	.quad	.LCFI2-.Ltext0
+	.quad	.LFE0-.Ltext0
+	.value	0x2
+	.byte	0x77
+	.sleb128 8
+	.quad	0
+	.quad	0
+.LLST1:
+	.quad	.LFB1-.Ltext0
+	.quad	.LCFI3-.Ltext0
+	.value	0x2
+	.byte	0x77
+	.sleb128 8
+	.quad	.LCFI3-.Ltext0
+	.quad	.LCFI4-.Ltext0
+	.value	0x2
+	.byte	0x77
+	.sleb128 16
+	.quad	.LCFI4-.Ltext0
+	.quad	.LCFI5-.Ltext0
+	.value	0x2
+	.byte	0x76
+	.sleb128 16
+	.quad	.LCFI5-.Ltext0
+	.quad	.LFE1-.Ltext0
+	.value	0x2
+	.byte	0x77
+	.sleb128 8
+	.quad	0
+	.quad	0
+.LLST2:
+	.quad	.LFB2-.Ltext0
+	.quad	.LCFI6-.Ltext0
+	.value	0x2
+	.byte	0x77
+	.sleb128 8
+	.quad	.LCFI6-.Ltext0
+	.quad	.LCFI7-.Ltext0
+	.value	0x2
+	.byte	0x77
+	.sleb128 16
+	.quad	.LCFI7-.Ltext0
+	.quad	.LCFI8-.Ltext0
+	.value	0x2
+	.byte	0x76
+	.sleb128 16
+	.quad	.LCFI8-.Ltext0
+	.quad	.LFE2-.Ltext0
+	.value	0x2
+	.byte	0x77
+	.sleb128 8
+	.quad	0
+	.quad	0
+	.section	.debug_aranges,"",@progbits
+	.long	0x2c
+	.value	0x2
+	.long	.Ldebug_info0
+	.byte	0x8
+	.byte	0
+	.value	0
+	.value	0
+	.quad	.Ltext0
+	.quad	.Letext0-.Ltext0
+	.quad	0
+	.quad	0
+	.section	.debug_line,"",@progbits
+.Ldebug_line0:
+	.section	.debug_str,"MS",@progbits,1
+.LASF0:
+	.string	"stop_frame"
+.LASF3:
+	.string	"dw2-undefined-ret-addr.c"
+.LASF2:
+	.string	"GNU C 4.7.2"
+.LASF1:
+	.string	"first_frame"
+.LASF5:
+	.string	"main"
+.LASF4:
+	.string	"/home/username/src/gdb/testsuite/gdb.dwarf2"
+	.ident	"GCC: (GNU) 4.7.2"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.c b/gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.c
new file mode 100644
index 0000000..6c5b06a
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.c
@@ -0,0 +1,36 @@
+/*
+   Copyright 2013 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+void
+stop_frame ()
+{
+  /* The debug information for this frame is modified in the accompanying
+     .S file, to mark the return address as undefined.  */
+}
+
+void
+first_frame ()
+{
+  stop_frame ();
+}
+
+int
+main ()
+{
+  first_frame ();
+
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.exp b/gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.exp
new file mode 100644
index 0000000..40ac356
--- /dev/null
+++ b/gdb/testsuite/gdb.dwarf2/dw2-undefined-ret-addr.exp
@@ -0,0 +1,58 @@
+# Copyright 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+load_lib dwarf.exp
+
+standard_testfile .S
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+if ![dwarf2_support] {
+    return 0
+}
+
+# This test can only be run on x86-64 targets.
+if {![istarget x86_64-*] || ![is_lp64_target]} {
+    return 0
+}
+
+if {[prepare_for_testing "$testfile.exp" "$testfile" $srcfile {nodebug}]} {
+    return -1
+}
+
+if ![runto "stop_frame"] {
+    return -1
+}
+
+# stop_frame should be the outermost frame.
+
+# Check that backtrace shows only frame #0.
+gdb_test "bt" "#0\[ \]\+stop_frame \[^\r\n\]\+"
+
+# And that "up" doesn't work.
+gdb_test "up" \
+    "Initial frame selected; you cannot go up\\." \
+    "up refuses to go up"
+
+# "info frame" unwinds the PC for "saved ... = ".  Make sure that
+# doesn't cause an error, and shows "<not saved>".
+gdb_test "info frame" [join [list \
+    "Stack level 0, frame at $hex\:" \
+    " rip = $hex in stop_frame \\(dw2-undefined-ret-addr\\.c:22\\); saved rip = <not saved>" \
+    " Outermost frame: outermost" \
+    " source language c\\." \
+    " Arglist at $hex, args\: " \
+    " Locals at $hex, Previous frame's sp is $hex" \
+    " Saved registers\:" \
+    "  rbp at $hex.*" \
+] "\r\n"]
diff --git a/gdb/valprint.c b/gdb/valprint.c
index 0124934..7ebcdfd 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -339,12 +339,18 @@ void
 val_print_optimized_out (const struct value *val, struct ui_file *stream)
 {
   if (val != NULL && value_lval_const (val) == lval_register)
-    fprintf_filtered (stream, _("<not saved>"));
+    val_print_not_saved (stream);
   else
     fprintf_filtered (stream, _("<optimized out>"));
 }
 
 void
+val_print_not_saved (struct ui_file *stream)
+{
+  fprintf_filtered (stream, _("<not saved>"));
+}
+
+void
 val_print_unavailable (struct ui_file *stream)
 {
   fprintf_filtered (stream, _("<unavailable>"));
diff --git a/gdb/valprint.h b/gdb/valprint.h
index 1d86ed7..8ed259d 100644
--- a/gdb/valprint.h
+++ b/gdb/valprint.h
@@ -163,6 +163,9 @@ extern int read_string (CORE_ADDR addr, int len, int width,
 extern void val_print_optimized_out (const struct value *val,
 				     struct ui_file *stream);
 
+/* Prints "<not saved>" to STREAM.  */
+extern void val_print_not_saved (struct ui_file *stream);
+
 extern void val_print_unavailable (struct ui_file *stream);
 
 extern void val_print_invalid_address (struct ui_file *stream);
-- 
1.7.11.7

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/2] New OPTIMIZED_OUT_ERROR error code.
  2013-11-29 20:16 [PATCH 0/2] Fix "info frame" in the outermost frame Pedro Alves
  2013-11-29 20:20 ` [PATCH 2/2] " Pedro Alves
@ 2013-11-29 20:39 ` Pedro Alves
  2013-12-02 13:53   ` Andrew Burgess
  2013-12-06 20:01 ` [PATCH 0/2] Fix "info frame" in the outermost frame Pedro Alves
  2 siblings, 1 reply; 9+ messages in thread
From: Pedro Alves @ 2013-11-29 20:39 UTC (permalink / raw)
  To: gdb-patches

In order to catch <optimized out> errors like we catch <unavailable>
errors, this adds a new OPTIMIZED_OUT_ERROR error code, and throws it
in various places.

gdb/ChangeLog
2013-11-29  Andrew Burgess  <aburgess@broadcom.com>
	    Pedro Alves  <palves@redhat.com>

	* exceptions.h (errors): Add OPTIMIZED_OUT_ERROR.
	* dwarf2loc.c (write_pieced_value): Throw OPTIMIZED_OUT_ERROR.
	* frame.c (frame_unwind_register): Throw OPTIMIZED_OUT_ERROR.
	* spu-tdep.c (spu_software_single_step): Throw
	OPTIMIZED_OUT_ERROR.
	* valops.c (value_assign): Throw OPTIMIZED_OUT_ERROR.
---
 gdb/dwarf2loc.c  | 7 ++++---
 gdb/exceptions.h | 4 ++++
 gdb/frame.c      | 3 ++-
 gdb/spu-tdep.c   | 5 +++--
 gdb/valops.c     | 3 ++-
 5 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 2d15546..2b1f323 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -1893,9 +1893,10 @@ write_pieced_value (struct value *to, struct value *from)
 						   &optim, &unavail))
 		      {
 			if (optim)
-			  error (_("Can't do read-modify-write to "
-				   "update bitfield; containing word has been "
-				   "optimized out"));
+			  throw_error (OPTIMIZED_OUT_ERROR,
+				       _("Can't do read-modify-write to "
+					 "update bitfield; containing word "
+					 "has been optimized out"));
 			if (unavail)
 			  throw_error (NOT_AVAILABLE_ERROR,
 				       _("Can't do read-modify-write to update "
diff --git a/gdb/exceptions.h b/gdb/exceptions.h
index 129d29a..237764d 100644
--- a/gdb/exceptions.h
+++ b/gdb/exceptions.h
@@ -86,6 +86,10 @@ enum errors {
      traceframe.  */
   NOT_AVAILABLE_ERROR,
 
+  /* Value was optimized out.  Note: if the value was a register, this
+     means the register was not saved in the frame.  */
+  OPTIMIZED_OUT_ERROR,
+
   /* DW_OP_GNU_entry_value resolving failed.  */
   NO_ENTRY_VALUE_ERROR,
 
diff --git a/gdb/frame.c b/gdb/frame.c
index db94d98..69a8059 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1007,7 +1007,8 @@ frame_unwind_register (struct frame_info *frame, int regnum, gdb_byte *buf)
 			 &lval, &addr, &realnum, buf);
 
   if (optimized)
-    error (_("Register %d was not saved"), regnum);
+    throw_error (OPTIMIZED_OUT_ERROR,
+		 _("Register %d was not saved"), regnum);
   if (unavailable)
     throw_error (NOT_AVAILABLE_ERROR,
 		 _("Register %d is not available"), regnum);
diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c
index fd54b1e..fdf435e 100644
--- a/gdb/spu-tdep.c
+++ b/gdb/spu-tdep.c
@@ -1614,8 +1614,9 @@ spu_software_single_step (struct frame_info *frame)
 	  else
 	    {
 	      if (optim)
-		error (_("Could not determine address of "
-			 "single-step breakpoint."));
+		throw_error (OPTIMIZED_OUT_ERROR,
+			     _("Could not determine address of "
+			       "single-step breakpoint."));
 	      if (unavail)
 		throw_error (NOT_AVAILABLE_ERROR,
 			     _("Could not determine address of "
diff --git a/gdb/valops.c b/gdb/valops.c
index 8e7b16f..d43c758 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -1188,7 +1188,8 @@ value_assign (struct value *toval, struct value *fromval)
 					       &optim, &unavail))
 		  {
 		    if (optim)
-		      error (_("value has been optimized out"));
+		      throw_error (OPTIMIZED_OUT_ERROR,
+				   _("value has been optimized out"));
 		    if (unavail)
 		      throw_error (NOT_AVAILABLE_ERROR,
 				   _("value is not available"));
-- 
1.7.11.7

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] Fix "info frame" in the outermost frame.
  2013-11-29 20:20 ` [PATCH 2/2] " Pedro Alves
@ 2013-12-02  9:04   ` Yao Qi
  2013-12-02 10:05     ` Pedro Alves
  2013-12-08  2:40   ` Yao Qi
  1 sibling, 1 reply; 9+ messages in thread
From: Yao Qi @ 2013-12-02  9:04 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 11/30/2013 04:15 AM, Pedro Alves wrote:
> A new test is added.  It's based off dw2-reg-undefined.exp, and tweaked to
> mark the return address (rip) of "stop_frame" as undefined.

Can we use dwarf assembler to create needed dwarf info?

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] Fix "info frame" in the outermost frame.
  2013-12-02  9:04   ` Yao Qi
@ 2013-12-02 10:05     ` Pedro Alves
  0 siblings, 0 replies; 9+ messages in thread
From: Pedro Alves @ 2013-12-02 10:05 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

On 12/02/2013 09:02 AM, Yao Qi wrote:
> On 11/30/2013 04:15 AM, Pedro Alves wrote:
>> A new test is added.  It's based off dw2-reg-undefined.exp, and tweaked to
>> mark the return address (rip) of "stop_frame" as undefined.
> 
> Can we use dwarf assembler to create needed dwarf info?

Yeah, I had the same question for the dwarf2-unspecified-ret-addr.exp
test (that has been reverted meanwhile), but the dwarf assembler
doesn't do CFI.

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] New OPTIMIZED_OUT_ERROR error code.
  2013-11-29 20:39 ` [PATCH 1/2] New OPTIMIZED_OUT_ERROR error code Pedro Alves
@ 2013-12-02 13:53   ` Andrew Burgess
  0 siblings, 0 replies; 9+ messages in thread
From: Andrew Burgess @ 2013-12-02 13:53 UTC (permalink / raw)
  To: gdb-patches

On 29/11/2013 8:15 PM, Pedro Alves wrote:
> In order to catch <optimized out> errors like we catch <unavailable>
> errors, this adds a new OPTIMIZED_OUT_ERROR error code, and throws it
> in various places.
> 
> gdb/ChangeLog
> 2013-11-29  Andrew Burgess  <aburgess@broadcom.com>
> 	    Pedro Alves  <palves@redhat.com>
> 
> 	* exceptions.h (errors): Add OPTIMIZED_OUT_ERROR.
> 	* dwarf2loc.c (write_pieced_value): Throw OPTIMIZED_OUT_ERROR.
> 	* frame.c (frame_unwind_register): Throw OPTIMIZED_OUT_ERROR.
> 	* spu-tdep.c (spu_software_single_step): Throw
> 	OPTIMIZED_OUT_ERROR.
> 	* valops.c (value_assign): Throw OPTIMIZED_OUT_ERROR.

For what it's worth; looks good to me :)

Thanks,
Andrew


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 0/2] Fix "info frame" in the outermost frame.
  2013-11-29 20:16 [PATCH 0/2] Fix "info frame" in the outermost frame Pedro Alves
  2013-11-29 20:20 ` [PATCH 2/2] " Pedro Alves
  2013-11-29 20:39 ` [PATCH 1/2] New OPTIMIZED_OUT_ERROR error code Pedro Alves
@ 2013-12-06 20:01 ` Pedro Alves
  2 siblings, 0 replies; 9+ messages in thread
From: Pedro Alves @ 2013-12-06 20:01 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

FYI, I've pushed this.

Andrew, I had been playing with git commit --amend --date,
and reset the author of patch 1 to me by mistake.  I only
noticed it too late, after pushing...  sorry.

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] Fix "info frame" in the outermost frame.
  2013-11-29 20:20 ` [PATCH 2/2] " Pedro Alves
  2013-12-02  9:04   ` Yao Qi
@ 2013-12-08  2:40   ` Yao Qi
  2013-12-09 10:58     ` Pedro Alves
  1 sibling, 1 reply; 9+ messages in thread
From: Yao Qi @ 2013-12-08  2:40 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches

On 11/30/2013 04:15 AM, Pedro Alves wrote:
>     CORE_ADDR caller_pc;
> +  volatile struct gdb_exception ex;
>   
>     fi = parse_frame_specification_1 (addr_exp, "No stack.", &selected_frame_p);
>     gdbarch = get_frame_arch (fi);
> @@ -1493,11 +1494,29 @@ frame_info (char *addr_exp, int from_tty)
>   		     sal.line);
>     puts_filtered ("; ");
>     wrap_here ("    ");
> -  printf_filtered ("saved %s ", pc_regname);
> -  if (frame_unwind_caller_pc_if_available (fi, &caller_pc))
> -    fputs_filtered (paddress (gdbarch, caller_pc), gdb_stdout);
> +  printf_filtered ("saved %s = ", pc_regname);
> +
> +  TRY_CATCH (ex, RETURN_MASK_ERROR)
> +    {
> +      caller_pc = frame_unwind_caller_pc (fi);
> +    }
> +  if (ex.reason < 0)
> +    {
> +      switch (ex.error)
> +	{
> +	case NOT_AVAILABLE_ERROR:
> +	  val_print_unavailable (gdb_stdout);
> +	  break;
> +	case OPTIMIZED_OUT_ERROR:
> +	  val_print_not_saved (gdb_stdout);
> +	  break;
> +	default:
> +	  fprintf_filtered (gdb_stdout, _("<error: %s>"), ex.message);
> +	  break;
> +	}
> +    }
>     else
> -    fputs_filtered ("<unavailable>", gdb_stdout);
> +    fputs_filtered (paddress (gdbarch, caller_pc), gdb_stdout);

Subject: [PATCH] Avoid "may be used uninitialized" warning

Hi,
I see such warning below on one compiler I am using.

cc1: warnings being treated as errors
../../workspace/gdb/stack.c: In function 'frame_info':
../../workspace/gdb/stack.c:1519:20: error: 'caller_pc' may be used uninitialized in this function

Go through the gdb-patches archives and find the "canonical" way to
fix this warning is to initialize the variable.  Patch is
pushed.

gdb:

2013-12-08  Yao Qi  <yao@codesourcery.com>

	* stack.c (frame_info): Initialize variable caller_pc.
---
 gdb/ChangeLog |    4 ++++
 gdb/stack.c   |    3 ++-
 2 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 4748392..252aa69 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,7 @@
+2013-12-08  Yao Qi  <yao@codesourcery.com>
+
+	* stack.c (frame_info): Initialize variable caller_pc.
+
 2013-12-06  Pedro Alves  <palves@redhat.com>
 
 	* frame.c (enum cached_copy_status): New enum.
diff --git a/gdb/stack.c b/gdb/stack.c
index 848bcb0a..f45bb80 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1407,7 +1407,8 @@ frame_info (char *addr_exp, int from_tty)
   struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
   CORE_ADDR frame_pc;
   int frame_pc_p;
-  CORE_ADDR caller_pc;
+  /* Initialize it to avoid "may be used uninitialized" warning.  */
+  CORE_ADDR caller_pc = 0;
   volatile struct gdb_exception ex;
 
   fi = parse_frame_specification_1 (addr_exp, "No stack.", &selected_frame_p);

-- 
Yao (齐尧)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] Fix "info frame" in the outermost frame.
  2013-12-08  2:40   ` Yao Qi
@ 2013-12-09 10:58     ` Pedro Alves
  0 siblings, 0 replies; 9+ messages in thread
From: Pedro Alves @ 2013-12-09 10:58 UTC (permalink / raw)
  To: Yao Qi; +Cc: gdb-patches

On 12/08/2013 02:38 AM, Yao Qi wrote:

> Go through the gdb-patches archives and find the "canonical" way to
> fix this warning is to initialize the variable.  Patch is
> pushed.

Thanks Yao.

-- 
Pedro Alves

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2013-12-09 10:58 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-29 20:16 [PATCH 0/2] Fix "info frame" in the outermost frame Pedro Alves
2013-11-29 20:20 ` [PATCH 2/2] " Pedro Alves
2013-12-02  9:04   ` Yao Qi
2013-12-02 10:05     ` Pedro Alves
2013-12-08  2:40   ` Yao Qi
2013-12-09 10:58     ` Pedro Alves
2013-11-29 20:39 ` [PATCH 1/2] New OPTIMIZED_OUT_ERROR error code Pedro Alves
2013-12-02 13:53   ` Andrew Burgess
2013-12-06 20:01 ` [PATCH 0/2] Fix "info frame" in the outermost frame Pedro Alves

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).