public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/5] Frame debug output improvements
@ 2021-06-28 17:44 Simon Marchi
  2021-06-28 17:44 ` [PATCH 1/5] gdb: make frame_debug a boolean Simon Marchi
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: Simon Marchi @ 2021-06-28 17:44 UTC (permalink / raw)
  To: gdb-patches

I started improving the frame debug messages a while ago, while helping
Eli figure out why GDB couldn't unwind past a JIT frame.  I've been
sitting on these changes since, and finally cleaned them up for
submission.

While doing so, I found a little bug (that only happens when "set debug
frame" is in effect), which is fixed by patch 2.

Simon Marchi (5):
  gdb: make frame_debug a boolean
  gdb: value_fetch_lazy_register: fix getting frame id while it is
    computed
  gdb: introduce frame_debug_printf
  gdb: add names to unwinders, add debug messages when looking for
    unwinder
  gdb: introduce FRAME_SCOPED_DEBUG_ENTER_EXIT

 gdb/aarch64-tdep.c                            |   2 +
 gdb/alpha-mdebug-tdep.c                       |   4 +-
 gdb/alpha-tdep.c                              |   8 +-
 gdb/amd64-obsd-tdep.c                         |   4 +-
 gdb/amd64-tdep.c                              |   3 +
 gdb/amd64-windows-tdep.c                      |  76 ++--
 gdb/arc-tdep.c                                |   2 +
 gdb/arm-tdep.c                                |   5 +
 gdb/avr-tdep.c                                |   1 +
 gdb/bfin-tdep.c                               |   1 +
 gdb/bpf-tdep.c                                |   1 +
 gdb/cris-tdep.c                               |   2 +
 gdb/csky-tdep.c                               |   2 +
 gdb/dummy-frame.c                             |   1 +
 gdb/dwarf2/frame-tailcall.c                   |   1 +
 gdb/dwarf2/frame.c                            |   2 +
 gdb/frame-unwind.c                            |  12 +-
 gdb/frame-unwind.h                            |   1 +
 gdb/frame.c                                   | 335 +++++++-----------
 gdb/frame.h                                   |  13 +-
 gdb/frv-linux-tdep.c                          |   1 +
 gdb/frv-tdep.c                                |   1 +
 gdb/ft32-tdep.c                               |   1 +
 gdb/h8300-tdep.c                              |   1 +
 gdb/hppa-linux-tdep.c                         |   1 +
 gdb/hppa-tdep.c                               |   3 +
 gdb/i386-obsd-tdep.c                          |   1 +
 gdb/i386-tdep.c                               |   4 +
 gdb/ia64-tdep.c                               |   4 +
 gdb/inline-frame.c                            |   1 +
 gdb/iq2000-tdep.c                             |   1 +
 gdb/jit.c                                     |   1 +
 gdb/lm32-tdep.c                               |   1 +
 gdb/m32c-tdep.c                               |   1 +
 gdb/m32r-linux-tdep.c                         |   1 +
 gdb/m32r-tdep.c                               |   1 +
 gdb/m68hc11-tdep.c                            |   1 +
 gdb/m68k-linux-tdep.c                         |   1 +
 gdb/m68k-tdep.c                               |   1 +
 gdb/mep-tdep.c                                |   1 +
 gdb/microblaze-tdep.c                         |   1 +
 gdb/mips-sde-tdep.c                           |   1 +
 gdb/mips-tdep.c                               |   4 +
 gdb/mn10300-tdep.c                            |   1 +
 gdb/moxie-tdep.c                              |   1 +
 gdb/msp430-tdep.c                             |   1 +
 gdb/nds32-tdep.c                              |   2 +
 gdb/nios2-tdep.c                              |   2 +
 gdb/or1k-tdep.c                               |   1 +
 gdb/ppc-fbsd-tdep.c                           |   1 +
 gdb/ppc-obsd-tdep.c                           |   1 +
 gdb/python/py-unwind.c                        |   1 +
 gdb/record-btrace.c                           |   2 +
 gdb/riscv-tdep.c                              |   1 +
 gdb/rl78-tdep.c                               |   1 +
 gdb/rs6000-aix-tdep.c                         |   1 +
 gdb/rs6000-tdep.c                             |   2 +
 gdb/rx-tdep.c                                 |   2 +
 gdb/s12z-tdep.c                               |   1 +
 gdb/s390-linux-tdep.c                         |   1 +
 gdb/s390-tdep.c                               |   2 +
 gdb/score-tdep.c                              |   1 +
 gdb/sentinel-frame.c                          |   1 +
 gdb/sh-tdep.c                                 |   2 +
 gdb/sparc-netbsd-tdep.c                       |   1 +
 gdb/sparc-obsd-tdep.c                         |   1 +
 gdb/sparc-sol2-tdep.c                         |   1 +
 gdb/sparc-tdep.c                              |   1 +
 gdb/sparc64-fbsd-tdep.c                       |   1 +
 gdb/sparc64-netbsd-tdep.c                     |   1 +
 gdb/sparc64-obsd-tdep.c                       |   2 +
 gdb/sparc64-sol2-tdep.c                       |   1 +
 gdb/sparc64-tdep.c                            |   1 +
 .../gdb.dwarf2/dw2-reg-undefined.exp          |   5 +-
 gdb/tic6x-tdep.c                              |   2 +
 gdb/tilegx-tdep.c                             |   1 +
 gdb/v850-tdep.c                               |   1 +
 gdb/value.c                                   |  51 ++-
 gdb/vax-tdep.c                                |   1 +
 gdb/xstormy16-tdep.c                          |   1 +
 gdb/xtensa-tdep.c                             |   1 +
 81 files changed, 327 insertions(+), 284 deletions(-)

-- 
2.32.0


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

* [PATCH 1/5] gdb: make frame_debug a boolean
  2021-06-28 17:44 [PATCH 0/5] Frame debug output improvements Simon Marchi
@ 2021-06-28 17:44 ` Simon Marchi
  2021-06-28 17:44 ` [PATCH 2/5] gdb: value_fetch_lazy_register: fix getting frame id while it is computed Simon Marchi
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Simon Marchi @ 2021-06-28 17:44 UTC (permalink / raw)
  To: gdb-patches

gdb/ChangeLog:

	* frame.h (frame_debug): Change type to bool.
	* frame.c (frame_debug): Change type to bool.
	(_initialize_frame): Adjust.

Change-Id: I27b5359a25ad53ac42618b5708a025c348a1eeda
---
 gdb/frame.c | 11 ++++++-----
 gdb/frame.h |  2 +-
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/gdb/frame.c b/gdb/frame.c
index d2e14c831a09..f85de2eaae29 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -330,7 +330,8 @@ scoped_restore_selected_frame::~scoped_restore_selected_frame ()
 
 /* Flag to control debugging.  */
 
-unsigned int frame_debug;
+bool frame_debug;
+
 static void
 show_frame_debug (struct ui_file *file, int from_tty,
 		  struct cmd_list_element *c, const char *value)
@@ -3195,11 +3196,11 @@ Literal \"unlimited\" or zero means no limit."),
      set_backtrace_option_defs, &set_backtrace_cmdlist, &show_backtrace_cmdlist);
 
   /* Debug this files internals.  */
-  add_setshow_zuinteger_cmd ("frame", class_maintenance, &frame_debug,  _("\
+  add_setshow_boolean_cmd ("frame", class_maintenance, &frame_debug,  _("\
 Set frame debugging."), _("\
 Show frame debugging."), _("\
 When non-zero, frame specific internal debugging is enabled."),
-			     NULL,
-			     show_frame_debug,
-			     &setdebuglist, &showdebuglist);
+			   NULL,
+			   show_frame_debug,
+			   &setdebuglist, &showdebuglist);
 }
diff --git a/gdb/frame.h b/gdb/frame.h
index da52522ad2aa..33ca5ab6f1f2 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -214,7 +214,7 @@ extern const struct frame_id outer_frame_id;
 
 /* Flag to control debugging.  */
 
-extern unsigned int frame_debug;
+extern bool frame_debug;
 
 /* Construct a frame ID.  The first parameter is the frame's constant
    stack address (typically the outer-bound), and the second the
-- 
2.32.0


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

* [PATCH 2/5] gdb: value_fetch_lazy_register: fix getting frame id while it is computed
  2021-06-28 17:44 [PATCH 0/5] Frame debug output improvements Simon Marchi
  2021-06-28 17:44 ` [PATCH 1/5] gdb: make frame_debug a boolean Simon Marchi
@ 2021-06-28 17:44 ` Simon Marchi
  2021-06-29  9:27   ` Andrew Burgess
  2021-06-28 17:44 ` [PATCH 3/5] gdb: introduce frame_debug_printf Simon Marchi
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Simon Marchi @ 2021-06-28 17:44 UTC (permalink / raw)
  To: gdb-patches

This gives an internal error:

    $ ./gdb -q -nx --data-directory=data-directory  -q testsuite/outputs/gdb.python/py-unwind/py-unwind -x /home/simark/src/binutils-gdb/gdb/testsuite/gdb.python/py-unwind.py -ex "set debug frame 1" -ex r
    ...
    /home/simark/src/binutils-gdb/gdb/frame.c:623: internal-error: frame_id get_frame_id(frame_info*): Assertion `fi->this_id.p != frame_id_status::COMPUTING' failed.

The backtrace is:

    #9  0x000055d0b48e294a in internal_error (file=0x55d0b4c71380 "/home/simark/src/binutils-gdb/gdb/frame.c", line=623, fmt=0x55d0b4c712a0 "%s: Assertion `%s' failed.") at /home/simark/src/binutils-gdb/gdbsupport/errors.cc:55
    #10 0x000055d0b28aade3 in get_frame_id (fi=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/frame.c:623
    #11 0x000055d0b28b5350 in get_prev_frame_id_by_id (id=<error reading variable: Cannot access memory at address 0xfffffffffffffd9c>) at /home/simark/src/binutils-gdb/gdb/frame.c:2601
    #12 0x000055d0b375a1ab in value_fetch_lazy_register (val=0x6110000b3500) at /home/simark/src/binutils-gdb/gdb/value.c:3955
    #13 0x000055d0b375a9e7 in value_fetch_lazy (val=0x6110000b3500) at /home/simark/src/binutils-gdb/gdb/value.c:4024
    #14 0x000055d0b28a0548 in value_of_register (regnum=6, frame=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/findvar.c:274
    #15 0x000055d0b301b05a in pending_framepy_read_register (self=0x7f79056bb7f0, args=0x7f790581aa90) at /home/simark/src/binutils-gdb/gdb/python/py-unwind.c:398
    <some Python frames>
    #27 0x000055d0b301c6b4 in pyuw_sniffer (self=0x62100018e250, this_frame=0x6210001ff5e0, cache_ptr=0x6210001ff5f8) at /home/simark/src/binutils-gdb/gdb/python/py-unwind.c:568
    #28 0x000055d0b28a6587 in frame_unwind_try_unwinder (this_frame=0x6210001ff5e0, this_cache=0x6210001ff5f8, unwinder=0x62100018e250) at /home/simark/src/binutils-gdb/gdb/frame-unwind.c:130
    #29 0x000055d0b28a67b5 in frame_unwind_find_by_frame (this_frame=0x6210001ff5e0, this_cache=0x6210001ff5f8) at /home/simark/src/binutils-gdb/gdb/frame-unwind.c:193
    #30 0x000055d0b28aa80f in compute_frame_id (fi=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/frame.c:585
    #31 0x000055d0b28aaeae in get_frame_id (fi=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/frame.c:635
    #32 0x000055d0b28b5350 in get_prev_frame_id_by_id (id=<error reading variable: Cannot access memory at address 0xfffffffffffffd9c>) at /home/simark/src/binutils-gdb/gdb/frame.c:2601
    #33 0x000055d0b375a1ab in value_fetch_lazy_register (val=0x6110000b3280) at /home/simark/src/binutils-gdb/gdb/value.c:3955
    #34 0x000055d0b375a9e7 in value_fetch_lazy (val=0x6110000b3280) at /home/simark/src/binutils-gdb/gdb/value.c:4024
    #35 0x000055d0b28a0548 in value_of_register (regnum=1, frame=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/findvar.c:274
    #36 0x000055d0b2826b1c in eval_op_register (expect_type=0x6210001949f0, exp=0x6030000d6840, noside=EVAL_NORMAL, name=0x60400003e2e8 "rbx") at /home/simark/src/binutils-gdb/gdb/eval.c:1074
    #37 0x000055d0b218139f in expr::register_operation::evaluate (this=0x60400003e2d0, expect_type=0x6210001949f0, exp=0x6030000d6840, noside=EVAL_NORMAL) at /home/simark/src/binutils-gdb/gdb/expop.h:830
    #38 0x000055d0b282f5d5 in expr::operation::evaluate_for_cast (this=0x60400003e2d0, expect_type=0x6210001949f0, exp=0x6030000d6840, noside=EVAL_NORMAL) at /home/simark/src/binutils-gdb/gdb/eval.c:2506
    #39 0x000055d0b2181c64 in expr::unop_cast_operation::evaluate (this=0x6030000d6870, expect_type=0x6210001949f0, exp=0x6030000d6840, noside=EVAL_NORMAL) at /home/simark/src/binutils-gdb/gdb/expop.h:1975
    #40 0x000055d0b2820b04 in expression::evaluate (this=0x6030000d6840, expect_type=0x6210001949f0, noside=EVAL_NORMAL) at /home/simark/src/binutils-gdb/gdb/eval.c:101
    #41 0x000055d0b2820c46 in evaluate_expression (exp=0x6030000d6840, expect_type=0x6210001949f0) at /home/simark/src/binutils-gdb/gdb/eval.c:115
    #42 0x000055d0b337b0fd in stap_probe::evaluate_argument (this=0x60f0000053b0, n=1, frame=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/stap-probe.c:1435
    #43 0x000055d0b32d86e8 in svr4_handle_solib_event () at /home/simark/src/binutils-gdb/gdb/solib-svr4.c:1932
    #44 0x000055d0b32f1f39 in handle_solib_event () at /home/simark/src/binutils-gdb/gdb/solib.c:1258
    #45 0x000055d0b21e6c62 in bpstat_stop_status (aspace=0x6030000554e0, bp_addr=0x7ffff7fd18d8, thread=0x61700003db80, ws=0x7ffcff02c708, stop_chain=0x0) at /home/simark/src/binutils-gdb/gdb/breakpoint.c:5470
    #46 0x000055d0b2aa44c2 in handle_signal_stop (ecs=0x7ffcff02c6e0) at /home/simark/src/binutils-gdb/gdb/infrun.c:6254
    #47 0x000055d0b2aa0962 in handle_inferior_event (ecs=0x7ffcff02c6e0) at /home/simark/src/binutils-gdb/gdb/infrun.c:5740
    #48 0x000055d0b2a94a0f in fetch_inferior_event () at /home/simark/src/binutils-gdb/gdb/infrun.c:4111

When the get_frame_id call is done at frame 31, on frame #0, the
id is not computed yet, and therefore compute_frame_id is called.
compute_frame_id looks for an unwinder, which goes through the Python
unwinders.  When value_fetch_lazy_register is called at frame 12,
get_frame_id is called again for frame #0.  But we are in the process of
computing that frame id, so it can't work.  The assert in get_frame_id
works as intended.

The second call to get_frame_id happens in

    VALUE_FRAME_ID (val)

at value.c:3955.  If we dig down this, we see that:

 1. VALUE_NEXT_FRAME_ID is called first, returning the next frame's id,
    stored in struct value (it happens to be the sentinel's frame id, in
    this case)
 2. it is passed to get_prev_frame_id_by_id
 3. frame_find_by_id is called on that, that returns the frame_info for
    the sentinel frame
 4. get_prev_frame is called on that, that returns a frame_info for our
    frame #0
 5. get_frame_id is called on that, this is where the gdb_assert fails.
 6. had the previous step worked, value_fetch_lazy_register would have
    called frame_find_by_id on it, to get the frame_info for frame #0

In the end, all value_fetch_lazy_register wants is a frame_info for the
value's frame.  In step 4, we have that.  In step 5, we fetch the
frame's id only to go back to a frame_info in step 6.  That seems
unnecessary, and causes the internal error.

Change value_fetch_lazy_register to do the more straightforward thing:

 - fetch the value's next frame id
 - fetch the frame info from that
 - fetch the prev frame from that (the value's frame)

With this change, the command shown above no longer asserts and the
produced message makes sense:

    { value_fetch_lazy (frame=0,regnum=1(rbx),...) -> register=1 bytes=[c0e0fff7ff7f0000] }

gdb/ChangeLog:

	* value.c (value_fetch_lazy_register): Don't use VALUE_FRAME_ID
	to fetch value's frame for debug message.

Change-Id: I294f06f8b32206d442da5355f1b897159414e5b6
---
 gdb/value.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/gdb/value.c b/gdb/value.c
index 9df035a50b3b..6c969a911376 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3883,8 +3883,6 @@ value_fetch_lazy_memory (struct value *val)
 static void
 value_fetch_lazy_register (struct value *val)
 {
-  struct frame_info *next_frame;
-  int regnum;
   struct type *type = check_typedef (value_type (val));
   struct value *new_val = val, *mark = value_mark ();
 
@@ -3896,8 +3894,8 @@ value_fetch_lazy_register (struct value *val)
     {
       struct frame_id next_frame_id = VALUE_NEXT_FRAME_ID (new_val);
 
-      next_frame = frame_find_by_id (next_frame_id);
-      regnum = VALUE_REGNUM (new_val);
+      frame_info *next_frame = frame_find_by_id (next_frame_id);
+      int regnum = VALUE_REGNUM (new_val);
 
       gdb_assert (next_frame != NULL);
 
@@ -3948,18 +3946,17 @@ value_fetch_lazy_register (struct value *val)
 
   if (frame_debug)
     {
-      struct gdbarch *gdbarch;
-      struct frame_info *frame;
-      /* VALUE_FRAME_ID is used here, instead of VALUE_NEXT_FRAME_ID,
-	 so that the frame level will be shown correctly.  */
-      frame = frame_find_by_id (VALUE_FRAME_ID (val));
-      regnum = VALUE_REGNUM (val);
-      gdbarch = get_frame_arch (frame);
+      frame_id next_frame_id = VALUE_NEXT_FRAME_ID (val);
+      frame_info *next_frame = frame_find_by_id (next_frame_id);
+      frame_info *value_frame = get_prev_frame (next_frame);
+
+      int regnum = VALUE_REGNUM (val);
+      gdbarch *gdbarch = get_frame_arch (value_frame);
 
       fprintf_unfiltered (gdb_stdlog,
 			  "{ value_fetch_lazy "
 			  "(frame=%d,regnum=%d(%s),...) ",
-			  frame_relative_level (frame), regnum,
+			  frame_relative_level (value_frame), regnum,
 			  user_reg_map_regnum_to_name (gdbarch, regnum));
 
       fprintf_unfiltered (gdb_stdlog, "->");
-- 
2.32.0


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

* [PATCH 3/5] gdb: introduce frame_debug_printf
  2021-06-28 17:44 [PATCH 0/5] Frame debug output improvements Simon Marchi
  2021-06-28 17:44 ` [PATCH 1/5] gdb: make frame_debug a boolean Simon Marchi
  2021-06-28 17:44 ` [PATCH 2/5] gdb: value_fetch_lazy_register: fix getting frame id while it is computed Simon Marchi
@ 2021-06-28 17:44 ` Simon Marchi
  2021-06-28 17:44 ` [PATCH 4/5] gdb: add names to unwinders, add debug messages when looking for unwinder Simon Marchi
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Simon Marchi @ 2021-06-28 17:44 UTC (permalink / raw)
  To: gdb-patches

Introduce frame_debug_printf, to convert the "frame" debug messages to
the new system.  Replace fprint_frame with a frame_info::to_string
method that returns a string, like what was done with
frame_id::to_string.  This makes it easier to use with
frame_debug_printf.

gdb/ChangeLog:

	* frame.h (frame_debug_printf): New.
	* frame.c: Use frame_debug_printf throughout when printing frame
	debug messages.
	* amd64-windows-tdep.c: Likewise.
	* value.c: Likewise.

gdb/testsuite/ChangeLog:

	* gdb.dwarf2/dw2-reg-undefined.exp: Update regexp.

Change-Id: I3c230b0814ea81c23af3e1aca1aac8d4ba91d726
---
 gdb/amd64-windows-tdep.c                      |  75 ++---
 gdb/frame.c                                   | 303 +++++++-----------
 gdb/frame.h                                   |   5 +
 .../gdb.dwarf2/dw2-reg-undefined.exp          |   5 +-
 gdb/value.c                                   |  28 +-
 5 files changed, 165 insertions(+), 251 deletions(-)

diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c
index e95b8330fd67..5442e5276539 100644
--- a/gdb/amd64-windows-tdep.c
+++ b/gdb/amd64-windows-tdep.c
@@ -756,14 +756,10 @@ amd64_windows_frame_decode_insns (struct frame_info *this_frame,
 			      (gdb_byte *) &ex_ui, sizeof (ex_ui)) != 0)
 	return;
 
-      if (frame_debug)
-	fprintf_unfiltered
-	  (gdb_stdlog,
-	   "amd64_windows_frame_decodes_insn: "
-	   "%s: ver: %02x, plgsz: %02x, cnt: %02x, frame: %02x\n",
-	   paddress (gdbarch, unwind_info),
-	   ex_ui.Version_Flags, ex_ui.SizeOfPrologue,
-	   ex_ui.CountOfCodes, ex_ui.FrameRegisterOffset);
+      frame_debug_printf ("%s: ver: %02x, plgsz: %02x, cnt: %02x, frame: %02x",
+			  paddress (gdbarch, unwind_info),
+			  ex_ui.Version_Flags, ex_ui.SizeOfPrologue,
+			  ex_ui.CountOfCodes, ex_ui.FrameRegisterOffset);
 
       /* Check version.  */
       if (PEX64_UWI_VERSION (ex_ui.Version_Flags) != 1
@@ -801,10 +797,9 @@ amd64_windows_frame_decode_insns (struct frame_info *this_frame,
 	  get_frame_register (this_frame, frreg, buf);
 	  save_addr = extract_unsigned_integer (buf, 8, byte_order);
 
-	  if (frame_debug)
-	    fprintf_unfiltered (gdb_stdlog, "   frame_reg=%s, val=%s\n",
-				gdbarch_register_name (gdbarch, frreg),
-				paddress (gdbarch, save_addr));
+	  frame_debug_printf ("   frame_reg=%s, val=%s",
+			      gdbarch_register_name (gdbarch, frreg),
+			      paddress (gdbarch, save_addr));
 	}
 
       /* Read opcodes.  */
@@ -835,10 +830,8 @@ amd64_windows_frame_decode_insns (struct frame_info *this_frame,
 	     prologue has been fully executed.  */
 	  if (cache->pc >= start + p[0] || cache->pc < start)
 	    {
-	      if (frame_debug)
-		fprintf_unfiltered
-		  (gdb_stdlog, "   op #%u: off=0x%02x, insn=0x%02x\n",
-		   (unsigned) (p - insns), p[0], p[1]);
+	      frame_debug_printf ("   op #%u: off=0x%02x, insn=0x%02x",
+				  (unsigned) (p - insns), p[0], p[1]);
 
 	      /* If there is no frame registers defined, the current value of
 		 rsp is used instead.  */
@@ -912,11 +905,11 @@ amd64_windows_frame_decode_insns (struct frame_info *this_frame,
 		}
 
 	      /* Display address where the register was saved.  */
-	      if (frame_debug && reg >= 0)
-		fprintf_unfiltered
-		  (gdb_stdlog, "     [reg %s at %s]\n",
-		   gdbarch_register_name (gdbarch, reg),
-		   paddress (gdbarch, cache->prev_reg_addr[reg]));
+	      if (reg >= 0)
+		frame_debug_printf ("     [reg %s at %s]",
+				    gdbarch_register_name (gdbarch, reg),
+				    paddress (gdbarch,
+					      cache->prev_reg_addr[reg]));
 	    }
 
 	  /* Adjust with the length of the opcode.  */
@@ -978,14 +971,11 @@ amd64_windows_frame_decode_insns (struct frame_info *this_frame,
 	  unwind_info =
 	    extract_unsigned_integer (d.rva_UnwindData, 4, byte_order);
 
-	  if (frame_debug)
-	    fprintf_unfiltered
-	      (gdb_stdlog,
-	       "amd64_windows_frame_decodes_insn (next in chain):"
-	       " unwind_data=%s, start_rva=%s, end_rva=%s\n",
-	       paddress (gdbarch, unwind_info),
-	       paddress (gdbarch, cache->start_rva),
-	       paddress (gdbarch, cache->end_rva));
+	  frame_debug_printf ("next in chain: unwind_data=%s, start_rva=%s, "
+			      "end_rva=%s",
+			      paddress (gdbarch, unwind_info),
+			      paddress (gdbarch, cache->start_rva),
+			      paddress (gdbarch, cache->end_rva));
 	}
 
       /* Allow the user to break this loop.  */
@@ -996,10 +986,9 @@ amd64_windows_frame_decode_insns (struct frame_info *this_frame,
     cache->prev_rip_addr = cur_sp;
   cache->prev_sp = cur_sp + 8;
 
-  if (frame_debug)
-    fprintf_unfiltered (gdb_stdlog, "   prev_sp: %s, prev_pc @%s\n",
-			paddress (gdbarch, cache->prev_sp),
-			paddress (gdbarch, cache->prev_rip_addr));
+  frame_debug_printf ("   prev_sp: %s, prev_pc @%s",
+		      paddress (gdbarch, cache->prev_sp),
+		      paddress (gdbarch, cache->prev_rip_addr));
 }
 
 /* Find SEH unwind info for PC, returning 0 on success.
@@ -1073,11 +1062,9 @@ amd64_windows_find_unwind_info (struct gdbarch *gdbarch, CORE_ADDR pc,
 	break;
     }
 
-  if (frame_debug)
-    fprintf_unfiltered
-      (gdb_stdlog,
-       "amd64_windows_find_unwind_data:  image_base=%s, unwind_data=%s\n",
-       paddress (gdbarch, base), paddress (gdbarch, *unwind_info));
+  frame_debug_printf ("image_base=%s, unwind_data=%s",
+		      paddress (gdbarch, base),
+		      paddress (gdbarch, *unwind_info));
 
   return 0;
 }
@@ -1139,11 +1126,9 @@ amd64_windows_frame_prev_register (struct frame_info *this_frame,
     amd64_windows_frame_cache (this_frame, this_cache);
   CORE_ADDR prev;
 
-  if (frame_debug)
-    fprintf_unfiltered (gdb_stdlog,
-			"amd64_windows_frame_prev_register %s for sp=%s\n",
-			gdbarch_register_name (gdbarch, regnum),
-			paddress (gdbarch, cache->prev_sp));
+  frame_debug_printf ("%s for sp=%s",
+		      gdbarch_register_name (gdbarch, regnum),
+		      paddress (gdbarch, cache->prev_sp));
 
   if (regnum >= AMD64_XMM0_REGNUM && regnum <= AMD64_XMM0_REGNUM + 15)
       prev = cache->prev_xmm_addr[regnum - AMD64_XMM0_REGNUM];
@@ -1160,8 +1145,8 @@ amd64_windows_frame_prev_register (struct frame_info *this_frame,
   else
     prev = 0;
 
-  if (prev && frame_debug)
-    fprintf_unfiltered (gdb_stdlog, "  -> at %s\n", paddress (gdbarch, prev));
+  if (prev != 0)
+    frame_debug_printf ("  -> at %s", paddress (gdbarch, prev));
 
   if (prev)
     {
diff --git a/gdb/frame.c b/gdb/frame.c
index f85de2eaae29..7b459680313a 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -111,6 +111,9 @@ enum class frame_id_status
 
 struct frame_info
 {
+  /* Return a string representation of this frame.  */
+  std::string to_string () const;
+
   /* Level of this frame.  The inner-most (youngest) frame is at level
      0.  As you move towards the outer-most (oldest) frame, the level
      increases.  This is a cached value.  It could just as easily be
@@ -414,95 +417,85 @@ frame_id::to_string () const
   return res;
 }
 
-static void
-fprint_frame_type (struct ui_file *file, enum frame_type type)
+/* Return a string representation of TYPE.  */
+
+static const char *
+frame_type_str (frame_type type)
 {
   switch (type)
     {
     case NORMAL_FRAME:
-      fprintf_unfiltered (file, "NORMAL_FRAME");
-      return;
+      return "NORMAL_FRAME";
+
     case DUMMY_FRAME:
-      fprintf_unfiltered (file, "DUMMY_FRAME");
-      return;
+      return "DUMMY_FRAME";
+
     case INLINE_FRAME:
-      fprintf_unfiltered (file, "INLINE_FRAME");
-      return;
+      return "INLINE_FRAME";
+
     case TAILCALL_FRAME:
-      fprintf_unfiltered (file, "TAILCALL_FRAME");
-      return;
+      return "TAILCALL_FRAME";
+
     case SIGTRAMP_FRAME:
-      fprintf_unfiltered (file, "SIGTRAMP_FRAME");
-      return;
+      return "SIGTRAMP_FRAME";
+
     case ARCH_FRAME:
-      fprintf_unfiltered (file, "ARCH_FRAME");
-      return;
+      return "ARCH_FRAME";
+
     case SENTINEL_FRAME:
-      fprintf_unfiltered (file, "SENTINEL_FRAME");
-      return;
+      return "SENTINEL_FRAME";
+
     default:
-      fprintf_unfiltered (file, "<unknown type>");
-      return;
+      return "<unknown type>";
     };
 }
 
-static void
-fprint_frame (struct ui_file *file, struct frame_info *fi)
+ /* See struct frame_info.  */
+
+std::string
+frame_info::to_string () const
 {
-  if (fi == NULL)
-    {
-      fprintf_unfiltered (file, "<NULL frame>");
-      return;
-    }
+  const frame_info *fi = this;
+
+  std::string res;
 
-  fprintf_unfiltered (file, "{");
-  fprintf_unfiltered (file, "level=%d", fi->level);
-  fprintf_unfiltered (file, ",");
+  res += string_printf ("{level=%d,", fi->level);
 
-  fprintf_unfiltered (file, "type=");
   if (fi->unwind != NULL)
-    fprint_frame_type (file, fi->unwind->type);
+    res += string_printf ("type=%s,", frame_type_str (fi->unwind->type));
   else
-    fprintf_unfiltered (file, "<unknown>");
-  fprintf_unfiltered (file, ",");
+    res += "type=<unknown>,";
 
-  fprintf_unfiltered (file, "unwind=");
   if (fi->unwind != NULL)
-    gdb_print_host_address (fi->unwind, file);
+    res += string_printf ("unwind=%p,", host_address_to_string (fi->unwind));
   else
-    fprintf_unfiltered (file, "<unknown>");
-  fprintf_unfiltered (file, ",");
+    res += "unwind=<unknown>,";
 
-  fprintf_unfiltered (file, "pc=");
   if (fi->next == NULL || fi->next->prev_pc.status == CC_UNKNOWN)
-    fprintf_unfiltered (file, "<unknown>");
+    res += "pc=<unknown>,";
   else if (fi->next->prev_pc.status == CC_VALUE)
-    {
-      fprintf_unfiltered (file, "%s", hex_string (fi->next->prev_pc.value));
-      if (fi->next->prev_pc.masked)
-	fprintf_unfiltered (file, "[PAC]");
-    }
+    res += string_printf ("pc=%s%s,", hex_string (fi->next->prev_pc.value),
+			  fi->next->prev_pc.masked ? "[PAC]" : "");
   else if (fi->next->prev_pc.status == CC_NOT_SAVED)
-    val_print_not_saved (file);
+    res += "pc=<not saved>,";
   else if (fi->next->prev_pc.status == CC_UNAVAILABLE)
-    val_print_unavailable (file);
-  fprintf_unfiltered (file, ",");
+    res += "pc=<unavailable>,";
 
-  fprintf_unfiltered (file, "id=");
   if (fi->this_id.p == frame_id_status::NOT_COMPUTED)
-    fprintf_unfiltered (file, "<not computed>");
+    res += "id=<not computed>,";
   else if (fi->this_id.p == frame_id_status::COMPUTING)
-    fprintf_unfiltered (file, "<computing>");
+    res += "id=<computing>,";
   else
-    fprintf_unfiltered (file, "%s", fi->this_id.value.to_string ().c_str ());
-  fprintf_unfiltered (file, ",");
+    res += string_printf ("id=%s,", fi->this_id.value.to_string ().c_str ());
 
-  fprintf_unfiltered (file, "func=");
   if (fi->next != NULL && fi->next->prev_func.status == CC_VALUE)
-    fprintf_unfiltered (file, "%s", hex_string (fi->next->prev_func.addr));
+    res += string_printf ("func=%s", hex_string (fi->next->prev_func.addr));
   else
-    fprintf_unfiltered (file, "<unknown>");
-  fprintf_unfiltered (file, "}");
+    res += "func=<unknown>";
+
+  res += "}";
+
+  return res;
 }
 
 /* Given FRAME, return the enclosing frame as found in real frames read-in from
@@ -576,9 +569,7 @@ compute_frame_id (struct frame_info *fi)
       /* Mark this frame's id as "being computed.  */
       fi->this_id.p = frame_id_status::COMPUTING;
 
-      if (frame_debug)
-	fprintf_unfiltered (gdb_stdlog, "{ compute_frame_id (fi=%d) ",
-			    fi->level);
+      frame_debug_printf ("fi=%d", fi->level);
 
       /* Find the unwinder.  */
       if (fi->unwind == NULL)
@@ -593,9 +584,7 @@ compute_frame_id (struct frame_info *fi)
       /* Mark this frame's id as "computed".  */
       fi->this_id.p = frame_id_status::COMPUTED;
 
-      if (frame_debug)
-	fprintf_unfiltered (gdb_stdlog, "-> %s }\n",
-			    fi->this_id.value.to_string ().c_str ());
+      frame_debug_printf ("  -> %s", fi->this_id.value.to_string ().c_str ());
     }
   catch (const gdb_exception &ex)
     {
@@ -746,9 +735,7 @@ frame_id_p (frame_id l)
   /* The frame is valid iff it has a valid stack address.  */
   bool p = l.stack_status != FID_STACK_INVALID;
 
-  if (frame_debug)
-    fprintf_unfiltered (gdb_stdlog, "{ frame_id_p (l=%s) -> %d }\n",
-			l.to_string ().c_str (), p);
+  frame_debug_printf ("l=%s -> %d", l.to_string ().c_str (), p);
 
   return p;
 }
@@ -791,9 +778,8 @@ frame_id_eq (frame_id l, frame_id r)
     /* Frames are equal.  */
     eq = true;
 
-  if (frame_debug)
-    fprintf_unfiltered (gdb_stdlog, "{ frame_id_eq (l=%s,r=%s) -> %d }\n",
-			l.to_string ().c_str (), r.to_string ().c_str (), eq);
+  frame_debug_printf ("l=%s, r=%s -> %d",
+		      l.to_string ().c_str (), r.to_string ().c_str (), eq);
 
   return eq;
 }
@@ -869,10 +855,9 @@ frame_id_inner (struct gdbarch *gdbarch, struct frame_id l, struct frame_id r)
        different .code and/or .special address).  */
     inner = gdbarch_inner_than (gdbarch, l.stack_addr, r.stack_addr);
 
-  if (frame_debug)
-    fprintf_unfiltered (gdb_stdlog, "{ frame_id_inner (l=%s,r=%s) -> %d }\n",
-			l.to_string ().c_str (), r.to_string ().c_str (),
-			inner);
+  frame_debug_printf ("is l=%s inner than r=%s? %d",
+		      l.to_string ().c_str (), r.to_string ().c_str (),
+		      inner);
 
   return inner;
 }
@@ -967,21 +952,15 @@ frame_unwind_pc (struct frame_info *this_frame)
 	    {
 	      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);
+	      frame_debug_printf ("this_frame=%d -> <unavailable>",
+				  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);
+	      frame_debug_printf ("this_frame=%d -> <not saved>",
+				  this_frame->level);
 	    }
 	  else
 	    throw;
@@ -991,12 +970,10 @@ frame_unwind_pc (struct frame_info *this_frame)
 	{
 	  this_frame->prev_pc.value = pc;
 	  this_frame->prev_pc.status = CC_VALUE;
-	  if (frame_debug)
-	    fprintf_unfiltered (gdb_stdlog,
-				"{ frame_unwind_pc (this_frame=%d) "
-				"-> %s }\n",
-				this_frame->level,
-				hex_string (this_frame->prev_pc.value));
+
+	  frame_debug_printf ("this_frame=%d -> %s",
+			      this_frame->level,
+			      hex_string (this_frame->prev_pc.value));
 	}
     }
 
@@ -1039,21 +1016,18 @@ get_frame_func_if_available (frame_info *this_frame, CORE_ADDR *pc)
       if (!get_frame_address_in_block_if_available (this_frame, &addr_in_block))
 	{
 	  next_frame->prev_func.status = CC_UNAVAILABLE;
-	  if (frame_debug)
-	    fprintf_unfiltered (gdb_stdlog,
-				"{ get_frame_func (this_frame=%d)"
-				" -> unavailable }\n",
-				this_frame->level);
+
+	  frame_debug_printf ("this_frame=%d -> unavailable",
+			      this_frame->level);
 	}
       else
 	{
 	  next_frame->prev_func.status = CC_VALUE;
 	  next_frame->prev_func.addr = get_pc_function_start (addr_in_block);
-	  if (frame_debug)
-	    fprintf_unfiltered (gdb_stdlog,
-				"{ get_frame_func (this_frame=%d) -> %s }\n",
-				this_frame->level,
-				hex_string (next_frame->prev_func.addr));
+
+	  frame_debug_printf ("this_frame=%d -> %s",
+			      this_frame->level,
+			      hex_string (next_frame->prev_func.addr));
 	}
     }
 
@@ -1247,14 +1221,9 @@ frame_unwind_register_value (frame_info *next_frame, int regnum)
   gdb_assert (next_frame != NULL);
   gdbarch = frame_unwind_arch (next_frame);
 
-  if (frame_debug)
-    {
-      fprintf_unfiltered (gdb_stdlog,
-			  "{ frame_unwind_register_value "
-			  "(frame=%d,regnum=%d(%s),...) ",
-			  next_frame->level, regnum,
-			  user_reg_map_regnum_to_name (gdbarch, regnum));
-    }
+  frame_debug_printf ("frame=%d, regnum=%d(%s)",
+		      next_frame->level, regnum,
+		      user_reg_map_regnum_to_name (gdbarch, regnum));
 
   /* Find the unwinder.  */
   if (next_frame->unwind == NULL)
@@ -1267,40 +1236,42 @@ frame_unwind_register_value (frame_info *next_frame, int regnum)
 
   if (frame_debug)
     {
-      fprintf_unfiltered (gdb_stdlog, "->");
+      string_file debug_file;
+
+      fprintf_unfiltered (&debug_file, "  ->");
       if (value_optimized_out (value))
 	{
-	  fprintf_unfiltered (gdb_stdlog, " ");
-	  val_print_not_saved (gdb_stdlog);
+	  fprintf_unfiltered (&debug_file, " ");
+	  val_print_not_saved (&debug_file);
 	}
       else
 	{
 	  if (VALUE_LVAL (value) == lval_register)
-	    fprintf_unfiltered (gdb_stdlog, " register=%d",
+	    fprintf_unfiltered (&debug_file, " register=%d",
 				VALUE_REGNUM (value));
 	  else if (VALUE_LVAL (value) == lval_memory)
-	    fprintf_unfiltered (gdb_stdlog, " address=%s",
+	    fprintf_unfiltered (&debug_file, " address=%s",
 				paddress (gdbarch,
 					  value_address (value)));
 	  else
-	    fprintf_unfiltered (gdb_stdlog, " computed");
+	    fprintf_unfiltered (&debug_file, " computed");
 
 	  if (value_lazy (value))
-	    fprintf_unfiltered (gdb_stdlog, " lazy");
+	    fprintf_unfiltered (&debug_file, " lazy");
 	  else
 	    {
 	      int i;
 	      const gdb_byte *buf = value_contents (value);
 
-	      fprintf_unfiltered (gdb_stdlog, " bytes=");
-	      fprintf_unfiltered (gdb_stdlog, "[");
+	      fprintf_unfiltered (&debug_file, " bytes=");
+	      fprintf_unfiltered (&debug_file, "[");
 	      for (i = 0; i < register_size (gdbarch, regnum); i++)
-		fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
-	      fprintf_unfiltered (gdb_stdlog, "]");
+		fprintf_unfiltered (&debug_file, "%02x", buf[i]);
+	      fprintf_unfiltered (&debug_file, "]");
 	    }
 	}
 
-      fprintf_unfiltered (gdb_stdlog, " }\n");
+      frame_debug_printf ("%s", debug_file.c_str ());
     }
 
   return value;
@@ -1610,12 +1581,9 @@ create_sentinel_frame (struct program_space *pspace, struct regcache *regcache)
   /* The sentinel frame has a special ID.  */
   frame->this_id.p = frame_id_status::COMPUTED;
   frame->this_id.value = sentinel_frame_id;
-  if (frame_debug)
-    {
-      fprintf_unfiltered (gdb_stdlog, "{ create_sentinel_frame (...) -> ");
-      fprint_frame (gdb_stdlog, frame);
-      fprintf_unfiltered (gdb_stdlog, " }\n");
-    }
+
+  frame_debug_printf ("  -> %s", frame->to_string ().c_str ());
+
   return frame;
 }
 
@@ -1939,12 +1907,7 @@ create_new_frame (CORE_ADDR addr, CORE_ADDR pc)
 {
   struct frame_info *fi;
 
-  if (frame_debug)
-    {
-      fprintf_unfiltered (gdb_stdlog,
-			  "{ create_new_frame (addr=%s, pc=%s) ",
-			  hex_string (addr), hex_string (pc));
-    }
+  frame_debug_printf ("addr=%s, pc=%s", hex_string (addr), hex_string (pc));
 
   fi = FRAME_OBSTACK_ZALLOC (struct frame_info);
 
@@ -1969,12 +1932,7 @@ create_new_frame (CORE_ADDR addr, CORE_ADDR pc)
   fi->this_id.p = frame_id_status::COMPUTED;
   fi->this_id.value = frame_id_build (addr, pc);
 
-  if (frame_debug)
-    {
-      fprintf_unfiltered (gdb_stdlog, "-> ");
-      fprint_frame (gdb_stdlog, fi);
-      fprintf_unfiltered (gdb_stdlog, " }\n");
-    }
+  frame_debug_printf ("  -> %s", fi->to_string ().c_str ());
 
   return fi;
 }
@@ -2047,8 +2005,8 @@ reinit_frame_cache (void)
   sentinel_frame = NULL;		/* Invalidate cache */
   select_frame (NULL);
   frame_stash_invalidate ();
-  if (frame_debug)
-    fprintf_unfiltered (gdb_stdlog, "{ reinit_frame_cache () }\n");
+
+  frame_debug_printf ("generation=%d", frame_cache_generation);
 }
 
 /* Find where a register is saved (in memory or another register).
@@ -2116,12 +2074,8 @@ get_prev_frame_if_no_cycle (struct frame_info *this_frame)
 	{
 	  /* Another frame with the same id was already in the stash.  We just
 	     detected a cycle.  */
-	  if (frame_debug)
-	    {
-	      fprintf_unfiltered (gdb_stdlog, "-> ");
-	      fprint_frame (gdb_stdlog, NULL);
-	      fprintf_unfiltered (gdb_stdlog, " // this frame has same ID }\n");
-	    }
+	  frame_debug_printf ("  -> nullptr // this frame has same ID");
+
 	  this_frame->stop_reason = UNWIND_SAME_ID;
 	  /* Unlink.  */
 	  prev_frame->next = NULL;
@@ -2157,23 +2111,17 @@ get_prev_frame_always_1 (struct frame_info *this_frame)
 
   if (frame_debug)
     {
-      fprintf_unfiltered (gdb_stdlog, "{ get_prev_frame_always (this_frame=");
       if (this_frame != NULL)
-	fprintf_unfiltered (gdb_stdlog, "%d", this_frame->level);
+	frame_debug_printf ("this_frame=%d", this_frame->level);
       else
-	fprintf_unfiltered (gdb_stdlog, "<NULL>");
-      fprintf_unfiltered (gdb_stdlog, ") ");
+	frame_debug_printf ("this_frame=nullptr");
     }
 
   /* Only try to do the unwind once.  */
   if (this_frame->prev_p)
     {
-      if (frame_debug)
-	{
-	  fprintf_unfiltered (gdb_stdlog, "-> ");
-	  fprint_frame (gdb_stdlog, this_frame->prev);
-	  fprintf_unfiltered (gdb_stdlog, " // cached \n");
-	}
+      frame_debug_printf ("  -> %s // cached",
+			  this_frame->prev->to_string ().c_str ());
       return this_frame->prev;
     }
 
@@ -2220,15 +2168,9 @@ get_prev_frame_always_1 (struct frame_info *this_frame)
 
   if (this_frame->stop_reason != UNWIND_NO_REASON)
     {
-      if (frame_debug)
-	{
-	  enum unwind_stop_reason reason = this_frame->stop_reason;
-
-	  fprintf_unfiltered (gdb_stdlog, "-> ");
-	  fprint_frame (gdb_stdlog, NULL);
-	  fprintf_unfiltered (gdb_stdlog, " // %s }\n",
-			      frame_stop_reason_symbol_string (reason));
-	}
+      frame_debug_printf
+	("  -> nullptr // %s",
+	 frame_stop_reason_symbol_string (this_frame->stop_reason));
       return NULL;
     }
 
@@ -2253,13 +2195,7 @@ get_prev_frame_always_1 (struct frame_info *this_frame)
 	morestack_name = morestack_msym->linkage_name ();
       if (!morestack_name || strcmp (morestack_name, "__morestack") != 0)
 	{
-	  if (frame_debug)
-	    {
-	      fprintf_unfiltered (gdb_stdlog, "-> ");
-	      fprint_frame (gdb_stdlog, NULL);
-	      fprintf_unfiltered (gdb_stdlog,
-				  " // this frame ID is inner }\n");
-	    }
+	  frame_debug_printf ("  -> nullptr // this frame ID is inner");
 	  this_frame->stop_reason = UNWIND_INNER_ID;
 	  return NULL;
 	}
@@ -2299,13 +2235,7 @@ get_prev_frame_always_1 (struct frame_info *this_frame)
       if ((lval == lval_memory && lval == nlval && addr == naddr)
 	  || (lval == lval_register && lval == nlval && realnum == nrealnum))
 	{
-	  if (frame_debug)
-	    {
-	      fprintf_unfiltered (gdb_stdlog, "-> ");
-	      fprint_frame (gdb_stdlog, NULL);
-	      fprintf_unfiltered (gdb_stdlog, " // no saved PC }\n");
-	    }
-
+	  frame_debug_printf ("  -> nullptr // no saved PC");
 	  this_frame->stop_reason = UNWIND_NO_SAVED_PC;
 	  this_frame->prev = NULL;
 	  return NULL;
@@ -2407,12 +2337,7 @@ get_prev_frame_raw (struct frame_info *this_frame)
   this_frame->prev = prev_frame;
   prev_frame->next = this_frame;
 
-  if (frame_debug)
-    {
-      fprintf_unfiltered (gdb_stdlog, "-> ");
-      fprint_frame (gdb_stdlog, prev_frame);
-      fprintf_unfiltered (gdb_stdlog, " }\n");
-    }
+  frame_debug_printf ("  -> %s", prev_frame->to_string ().c_str ());
 
   return prev_frame;
 }
@@ -2425,12 +2350,10 @@ frame_debug_got_null_frame (struct frame_info *this_frame,
 {
   if (frame_debug)
     {
-      fprintf_unfiltered (gdb_stdlog, "{ get_prev_frame (this_frame=");
       if (this_frame != NULL)
-	fprintf_unfiltered (gdb_stdlog, "%d", this_frame->level);
+	frame_debug_printf ("this_frame=%d -> %s", this_frame->level, reason);
       else
-	fprintf_unfiltered (gdb_stdlog, "<NULL>");
-      fprintf_unfiltered (gdb_stdlog, ") -> // %s}\n", reason);
+	frame_debug_printf ("this_frame=nullptr -> %s", reason);
     }
 }
 
@@ -2944,11 +2867,9 @@ frame_unwind_arch (struct frame_info *next_frame)
 
       next_frame->prev_arch.arch = arch;
       next_frame->prev_arch.p = true;
-      if (frame_debug)
-	fprintf_unfiltered (gdb_stdlog,
-			    "{ frame_unwind_arch (next_frame=%d) -> %s }\n",
-			    next_frame->level,
-			    gdbarch_bfd_arch_info (arch)->printable_name);
+      frame_debug_printf ("next_frame=%d -> %s",
+			  next_frame->level,
+			  gdbarch_bfd_arch_info (arch)->printable_name);
     }
 
   return next_frame->prev_arch.arch;
diff --git a/gdb/frame.h b/gdb/frame.h
index 33ca5ab6f1f2..f8314ad66ceb 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -216,6 +216,11 @@ extern const struct frame_id outer_frame_id;
 
 extern bool frame_debug;
 
+/* Print a "frame" debug statement.  */
+
+#define frame_debug_printf(fmt, ...) \
+  debug_prefixed_printf_cond (frame_debug, "frame", fmt, ##__VA_ARGS__)
+
 /* Construct a frame ID.  The first parameter is the frame's constant
    stack address (typically the outer-bound), and the second the
    frame's constant code address (typically the entry point).
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.exp b/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.exp
index 3a8bbcb2f2af..2473a41a0de0 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.exp
@@ -78,7 +78,10 @@ for {set f 0} {$f < 3} {incr f} {
 # Test that the debug log statement in frame_unwind_register_value produces
 # "not saved" and not "optimized out".
 gdb_test "set debug frame 1"
-gdb_test {print $rax} {frame_unwind_register_value[^\r\n]+rax[^\r\n]+not saved.*}
+gdb_test {print $rax} [multi_line \
+			{\[frame\] frame_unwind_register_value: frame=0, regnum=0\(rax\)} \
+			{\[frame\] frame_unwind_register_value:   -> <not saved>} \
+			{.*}]
 gdb_test "set debug frame 0"
 
 # Test that history values show "not saved" and not "optimized out".
diff --git a/gdb/value.c b/gdb/value.c
index 6c969a911376..7f4b4609dc00 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -3953,17 +3953,17 @@ value_fetch_lazy_register (struct value *val)
       int regnum = VALUE_REGNUM (val);
       gdbarch *gdbarch = get_frame_arch (value_frame);
 
-      fprintf_unfiltered (gdb_stdlog,
-			  "{ value_fetch_lazy "
-			  "(frame=%d,regnum=%d(%s),...) ",
+      string_file debug_file;
+      fprintf_unfiltered (&debug_file,
+			  "(frame=%d, regnum=%d(%s), ...) ",
 			  frame_relative_level (value_frame), regnum,
 			  user_reg_map_regnum_to_name (gdbarch, regnum));
 
-      fprintf_unfiltered (gdb_stdlog, "->");
+      fprintf_unfiltered (&debug_file, "->");
       if (value_optimized_out (new_val))
 	{
-	  fprintf_unfiltered (gdb_stdlog, " ");
-	  val_print_optimized_out (new_val, gdb_stdlog);
+	  fprintf_unfiltered (&debug_file, " ");
+	  val_print_optimized_out (new_val, &debug_file);
 	}
       else
 	{
@@ -3971,23 +3971,23 @@ value_fetch_lazy_register (struct value *val)
 	  const gdb_byte *buf = value_contents (new_val);
 
 	  if (VALUE_LVAL (new_val) == lval_register)
-	    fprintf_unfiltered (gdb_stdlog, " register=%d",
+	    fprintf_unfiltered (&debug_file, " register=%d",
 				VALUE_REGNUM (new_val));
 	  else if (VALUE_LVAL (new_val) == lval_memory)
-	    fprintf_unfiltered (gdb_stdlog, " address=%s",
+	    fprintf_unfiltered (&debug_file, " address=%s",
 				paddress (gdbarch,
 					  value_address (new_val)));
 	  else
-	    fprintf_unfiltered (gdb_stdlog, " computed");
+	    fprintf_unfiltered (&debug_file, " computed");
 
-	  fprintf_unfiltered (gdb_stdlog, " bytes=");
-	  fprintf_unfiltered (gdb_stdlog, "[");
+	  fprintf_unfiltered (&debug_file, " bytes=");
+	  fprintf_unfiltered (&debug_file, "[");
 	  for (i = 0; i < register_size (gdbarch, regnum); i++)
-	    fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]);
-	  fprintf_unfiltered (gdb_stdlog, "]");
+	    fprintf_unfiltered (&debug_file, "%02x", buf[i]);
+	  fprintf_unfiltered (&debug_file, "]");
 	}
 
-      fprintf_unfiltered (gdb_stdlog, " }\n");
+      frame_debug_printf ("%s", debug_file.c_str ());
     }
 
   /* Dispose of the intermediate values.  This prevents
-- 
2.32.0


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

* [PATCH 4/5] gdb: add names to unwinders, add debug messages when looking for unwinder
  2021-06-28 17:44 [PATCH 0/5] Frame debug output improvements Simon Marchi
                   ` (2 preceding siblings ...)
  2021-06-28 17:44 ` [PATCH 3/5] gdb: introduce frame_debug_printf Simon Marchi
@ 2021-06-28 17:44 ` Simon Marchi
  2021-06-28 17:44 ` [PATCH 5/5] gdb: introduce FRAME_SCOPED_DEBUG_ENTER_EXIT Simon Marchi
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Simon Marchi @ 2021-06-28 17:44 UTC (permalink / raw)
  To: gdb-patches

I wrote this while debugging a problem where the expected unwinder for a
frame wasn't used.  It adds messages to show which unwinders are
considered for a frame, why they are not selected (if an exception is
thrown), and finally which unwinder is selected in the end.

To be able to show a meaningful, human-readable name for the unwinders,
add a "name" field to struct frame_unwind, and update all instances to
include a name.

Here's an example of the output:

    [frame] frame_unwind_find_by_frame: this_frame=0
    [frame] frame_unwind_try_unwinder: trying unwinder "dummy"
    [frame] frame_unwind_try_unwinder: no
    [frame] frame_unwind_try_unwinder: trying unwinder "dwarf2 tailcall"
    [frame] frame_unwind_try_unwinder: no
    [frame] frame_unwind_try_unwinder: trying unwinder "inline"
    [frame] frame_unwind_try_unwinder: no
    [frame] frame_unwind_try_unwinder: trying unwinder "jit"
    [frame] frame_unwind_try_unwinder: no
    [frame] frame_unwind_try_unwinder: trying unwinder "python"
    [frame] frame_unwind_try_unwinder: no
    [frame] frame_unwind_try_unwinder: trying unwinder "amd64 epilogue"
    [frame] frame_unwind_try_unwinder: no
    [frame] frame_unwind_try_unwinder: trying unwinder "i386 epilogue"
    [frame] frame_unwind_try_unwinder: no
    [frame] frame_unwind_try_unwinder: trying unwinder "dwarf2"
    [frame] frame_unwind_try_unwinder: yes

gdb/ChangeLog:

	* frame-unwind.h (struct frame_unwind) <name>: New.  Update
	instances everywhere to include this field.
	* frame-unwind.c (frame_unwind_try_unwinder,
	frame_unwind_find_by_frame): Add debug messages.

Change-Id: I813f17777422425f0d08b22499817b23922e8ddb
---
 gdb/aarch64-tdep.c          |  2 ++
 gdb/alpha-mdebug-tdep.c     |  4 +++-
 gdb/alpha-tdep.c            |  8 ++++++--
 gdb/amd64-obsd-tdep.c       |  4 +++-
 gdb/amd64-tdep.c            |  3 +++
 gdb/amd64-windows-tdep.c    |  1 +
 gdb/arc-tdep.c              |  2 ++
 gdb/arm-tdep.c              |  5 +++++
 gdb/avr-tdep.c              |  1 +
 gdb/bfin-tdep.c             |  1 +
 gdb/bpf-tdep.c              |  1 +
 gdb/cris-tdep.c             |  2 ++
 gdb/csky-tdep.c             |  2 ++
 gdb/dummy-frame.c           |  1 +
 gdb/dwarf2/frame-tailcall.c |  1 +
 gdb/dwarf2/frame.c          |  2 ++
 gdb/frame-unwind.c          | 11 ++++++++++-
 gdb/frame-unwind.h          |  1 +
 gdb/frv-linux-tdep.c        |  1 +
 gdb/frv-tdep.c              |  1 +
 gdb/ft32-tdep.c             |  1 +
 gdb/h8300-tdep.c            |  1 +
 gdb/hppa-linux-tdep.c       |  1 +
 gdb/hppa-tdep.c             |  3 +++
 gdb/i386-obsd-tdep.c        |  1 +
 gdb/i386-tdep.c             |  4 ++++
 gdb/ia64-tdep.c             |  4 ++++
 gdb/inline-frame.c          |  1 +
 gdb/iq2000-tdep.c           |  1 +
 gdb/jit.c                   |  1 +
 gdb/lm32-tdep.c             |  1 +
 gdb/m32c-tdep.c             |  1 +
 gdb/m32r-linux-tdep.c       |  1 +
 gdb/m32r-tdep.c             |  1 +
 gdb/m68hc11-tdep.c          |  1 +
 gdb/m68k-linux-tdep.c       |  1 +
 gdb/m68k-tdep.c             |  1 +
 gdb/mep-tdep.c              |  1 +
 gdb/microblaze-tdep.c       |  1 +
 gdb/mips-sde-tdep.c         |  1 +
 gdb/mips-tdep.c             |  4 ++++
 gdb/mn10300-tdep.c          |  1 +
 gdb/moxie-tdep.c            |  1 +
 gdb/msp430-tdep.c           |  1 +
 gdb/nds32-tdep.c            |  2 ++
 gdb/nios2-tdep.c            |  2 ++
 gdb/or1k-tdep.c             |  1 +
 gdb/ppc-fbsd-tdep.c         |  1 +
 gdb/ppc-obsd-tdep.c         |  1 +
 gdb/python/py-unwind.c      |  1 +
 gdb/record-btrace.c         |  2 ++
 gdb/riscv-tdep.c            |  1 +
 gdb/rl78-tdep.c             |  1 +
 gdb/rs6000-aix-tdep.c       |  1 +
 gdb/rs6000-tdep.c           |  2 ++
 gdb/rx-tdep.c               |  2 ++
 gdb/s12z-tdep.c             |  1 +
 gdb/s390-linux-tdep.c       |  1 +
 gdb/s390-tdep.c             |  2 ++
 gdb/score-tdep.c            |  1 +
 gdb/sentinel-frame.c        |  1 +
 gdb/sh-tdep.c               |  2 ++
 gdb/sparc-netbsd-tdep.c     |  1 +
 gdb/sparc-obsd-tdep.c       |  1 +
 gdb/sparc-sol2-tdep.c       |  1 +
 gdb/sparc-tdep.c            |  1 +
 gdb/sparc64-fbsd-tdep.c     |  1 +
 gdb/sparc64-netbsd-tdep.c   |  1 +
 gdb/sparc64-obsd-tdep.c     |  2 ++
 gdb/sparc64-sol2-tdep.c     |  1 +
 gdb/sparc64-tdep.c          |  1 +
 gdb/tic6x-tdep.c            |  2 ++
 gdb/tilegx-tdep.c           |  1 +
 gdb/v850-tdep.c             |  1 +
 gdb/vax-tdep.c              |  1 +
 gdb/xstormy16-tdep.c        |  1 +
 gdb/xtensa-tdep.c           |  1 +
 77 files changed, 126 insertions(+), 5 deletions(-)

diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c
index dea16e729c03..4b5af4616af5 100644
--- a/gdb/aarch64-tdep.c
+++ b/gdb/aarch64-tdep.c
@@ -1116,6 +1116,7 @@ aarch64_prologue_prev_register (struct frame_info *this_frame,
 /* AArch64 prologue unwinder.  */
 static frame_unwind aarch64_prologue_unwind =
 {
+  "aarch64 prologue",
   NORMAL_FRAME,
   aarch64_prologue_frame_unwind_stop_reason,
   aarch64_prologue_this_id,
@@ -1210,6 +1211,7 @@ aarch64_stub_unwind_sniffer (const struct frame_unwind *self,
 /* AArch64 stub unwinder.  */
 static frame_unwind aarch64_stub_unwind =
 {
+  "aarch64 stub",
   NORMAL_FRAME,
   aarch64_stub_frame_unwind_stop_reason,
   aarch64_stub_this_id,
diff --git a/gdb/alpha-mdebug-tdep.c b/gdb/alpha-mdebug-tdep.c
index a062ad99a9f3..52d0bf02813f 100644
--- a/gdb/alpha-mdebug-tdep.c
+++ b/gdb/alpha-mdebug-tdep.c
@@ -333,7 +333,9 @@ alpha_mdebug_frame_sniffer (const struct frame_unwind *self,
   return 1;
 }
 
-static const struct frame_unwind alpha_mdebug_frame_unwind = {
+static const struct frame_unwind alpha_mdebug_frame_unwind =
+{
+  "alpha mdebug",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   alpha_mdebug_frame_this_id,
diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c
index 90ff81319454..7538c5603bb1 100644
--- a/gdb/alpha-tdep.c
+++ b/gdb/alpha-tdep.c
@@ -1012,7 +1012,9 @@ alpha_sigtramp_frame_sniffer (const struct frame_unwind *self,
   return 0;
 }
 
-static const struct frame_unwind alpha_sigtramp_frame_unwind = {
+static const struct frame_unwind alpha_sigtramp_frame_unwind =
+{
+  "alpha sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   alpha_sigtramp_frame_this_id,
@@ -1429,7 +1431,9 @@ alpha_heuristic_frame_prev_register (struct frame_info *this_frame,
   return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
 }
 
-static const struct frame_unwind alpha_heuristic_frame_unwind = {
+static const struct frame_unwind alpha_heuristic_frame_unwind =
+{
+  "alpha prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   alpha_heuristic_frame_this_id,
diff --git a/gdb/amd64-obsd-tdep.c b/gdb/amd64-obsd-tdep.c
index cdb09d0272bc..070f19635aab 100644
--- a/gdb/amd64-obsd-tdep.c
+++ b/gdb/amd64-obsd-tdep.c
@@ -402,10 +402,12 @@ amd64obsd_trapframe_sniffer (const struct frame_unwind *self,
 		   || (startswith (name, "Xintr"))));
 }
 
-static const struct frame_unwind amd64obsd_trapframe_unwind = {
+static const struct frame_unwind amd64obsd_trapframe_unwind =
+{
   /* FIXME: kettenis/20051219: This really is more like an interrupt
      frame, but SIGTRAMP_FRAME would print <signal handler called>,
      which really is not what we want here.  */
+  "amd64 openbsd trap",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   amd64obsd_trapframe_this_id,
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index 3afac3c7e601..c028e1bd0f65 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -2702,6 +2702,7 @@ amd64_frame_prev_register (struct frame_info *this_frame, void **this_cache,
 
 static const struct frame_unwind amd64_frame_unwind =
 {
+  "amd64 prologue",
   NORMAL_FRAME,
   amd64_frame_unwind_stop_reason,
   amd64_frame_this_id,
@@ -2846,6 +2847,7 @@ amd64_sigtramp_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind amd64_sigtramp_frame_unwind =
 {
+  "amd64 sigtramp",
   SIGTRAMP_FRAME,
   amd64_sigtramp_frame_unwind_stop_reason,
   amd64_sigtramp_frame_this_id,
@@ -2981,6 +2983,7 @@ amd64_epilogue_frame_this_id (struct frame_info *this_frame,
 
 static const struct frame_unwind amd64_epilogue_frame_unwind =
 {
+  "amd64 epilogue",
   NORMAL_FRAME,
   amd64_epilogue_frame_unwind_stop_reason,
   amd64_epilogue_frame_this_id,
diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c
index 5442e5276539..fe8a3a0b7aca 100644
--- a/gdb/amd64-windows-tdep.c
+++ b/gdb/amd64-windows-tdep.c
@@ -1178,6 +1178,7 @@ amd64_windows_frame_this_id (struct frame_info *this_frame, void **this_cache,
 
 static const struct frame_unwind amd64_windows_frame_unwind =
 {
+  "amd64 windows",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   &amd64_windows_frame_this_id,
diff --git a/gdb/arc-tdep.c b/gdb/arc-tdep.c
index 3afbf4264fe8..b793a18d8b9e 100644
--- a/gdb/arc-tdep.c
+++ b/gdb/arc-tdep.c
@@ -1922,6 +1922,7 @@ arc_sigtramp_frame_sniffer (const struct frame_unwind *self,
    accepts the frame.  */
 
 static const struct frame_unwind arc_frame_unwind = {
+  "arc prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   arc_frame_this_id,
@@ -1937,6 +1938,7 @@ static const struct frame_unwind arc_frame_unwind = {
    context.  */
 
 static const struct frame_unwind arc_sigtramp_frame_unwind = {
+  "arc sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   arc_sigtramp_frame_this_id,
diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 339e03271e7e..3d05e6daa6fa 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -2028,6 +2028,7 @@ arm_prologue_prev_register (struct frame_info *this_frame,
 }
 
 static frame_unwind arm_prologue_unwind = {
+  "arm prologue",
   NORMAL_FRAME,
   arm_prologue_unwind_stop_reason,
   arm_prologue_this_id,
@@ -2737,6 +2738,7 @@ arm_exidx_unwind_sniffer (const struct frame_unwind *self,
 }
 
 struct frame_unwind arm_exidx_unwind = {
+  "arm exidx",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   arm_prologue_this_id,
@@ -2840,6 +2842,7 @@ arm_epilogue_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind arm_epilogue_frame_unwind =
 {
+  "arm epilogue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   arm_epilogue_frame_this_id,
@@ -2961,6 +2964,7 @@ arm_stub_unwind_sniffer (const struct frame_unwind *self,
 }
 
 struct frame_unwind arm_stub_unwind = {
+  "arm stub",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   arm_stub_this_id,
@@ -3172,6 +3176,7 @@ arm_m_exception_unwind_sniffer (const struct frame_unwind *self,
 
 struct frame_unwind arm_m_exception_unwind =
 {
+  "arm m exception",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   arm_m_exception_this_id,
diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c
index 5853e692ae46..6ef73d545490 100644
--- a/gdb/avr-tdep.c
+++ b/gdb/avr-tdep.c
@@ -1154,6 +1154,7 @@ avr_frame_prev_register (struct frame_info *this_frame,
 }
 
 static const struct frame_unwind avr_frame_unwind = {
+  "avr prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   avr_frame_this_id,
diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c
index e3d6eee8832e..bdf8ab90a22e 100644
--- a/gdb/bfin-tdep.c
+++ b/gdb/bfin-tdep.c
@@ -374,6 +374,7 @@ bfin_frame_prev_register (struct frame_info *this_frame,
 
 static const struct frame_unwind bfin_frame_unwind =
 {
+  "bfin prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   bfin_frame_this_id,
diff --git a/gdb/bpf-tdep.c b/gdb/bpf-tdep.c
index a29cd90ba387..e520d5d3d49a 100644
--- a/gdb/bpf-tdep.c
+++ b/gdb/bpf-tdep.c
@@ -184,6 +184,7 @@ bpf_frame_prev_register (struct frame_info *this_frame,
 
 static const struct frame_unwind bpf_frame_unwind =
 {
+  "bpf prologue",
   NORMAL_FRAME,
   bpf_frame_unwind_stop_reason,
   bpf_frame_this_id,
diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c
index 01ef1604bffa..a0ff59487ed6 100644
--- a/gdb/cris-tdep.c
+++ b/gdb/cris-tdep.c
@@ -437,6 +437,7 @@ cris_sigtramp_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind cris_sigtramp_frame_unwind =
 {
+  "cris sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   cris_sigtramp_frame_this_id,
@@ -900,6 +901,7 @@ cris_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
 static const struct frame_unwind cris_frame_unwind = 
 {
+  "cris prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   cris_frame_this_id,
diff --git a/gdb/csky-tdep.c b/gdb/csky-tdep.c
index 609b684265f7..5940429e1921 100644
--- a/gdb/csky-tdep.c
+++ b/gdb/csky-tdep.c
@@ -1916,6 +1916,7 @@ csky_frame_prev_register (struct frame_info *this_frame,
    unwinder.  */
 
 static const struct frame_unwind csky_unwind_cache = {
+  "cski prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   csky_frame_this_id,
@@ -1999,6 +2000,7 @@ csky_stub_prev_register (struct frame_info *this_frame,
 }
 
 static frame_unwind csky_stub_unwind = {
+  "csky stub",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   csky_stub_this_id,
diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c
index 68a693797492..ed2c778be6c4 100644
--- a/gdb/dummy-frame.c
+++ b/gdb/dummy-frame.c
@@ -378,6 +378,7 @@ dummy_frame_this_id (struct frame_info *this_frame,
 
 const struct frame_unwind dummy_frame_unwind =
 {
+  "dummy",
   DUMMY_FRAME,
   default_frame_unwind_stop_reason,
   dummy_frame_this_id,
diff --git a/gdb/dwarf2/frame-tailcall.c b/gdb/dwarf2/frame-tailcall.c
index d27211e9a88e..f112b4ecca48 100644
--- a/gdb/dwarf2/frame-tailcall.c
+++ b/gdb/dwarf2/frame-tailcall.c
@@ -468,6 +468,7 @@ tailcall_frame_prev_arch (struct frame_info *this_frame,
 
 const struct frame_unwind dwarf2_tailcall_frame_unwind =
 {
+  "dwarf2 tailcall",
   TAILCALL_FRAME,
   default_frame_unwind_stop_reason,
   tailcall_frame_this_id,
diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c
index f8612c96f274..8d24559bb4da 100644
--- a/gdb/dwarf2/frame.c
+++ b/gdb/dwarf2/frame.c
@@ -1380,6 +1380,7 @@ dwarf2_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind dwarf2_frame_unwind =
 {
+  "dwarf2",
   NORMAL_FRAME,
   dwarf2_frame_unwind_stop_reason,
   dwarf2_frame_this_id,
@@ -1391,6 +1392,7 @@ static const struct frame_unwind dwarf2_frame_unwind =
 
 static const struct frame_unwind dwarf2_signal_frame_unwind =
 {
+  "dwarf2 signal",
   SIGTRAMP_FRAME,
   dwarf2_frame_unwind_stop_reason,
   dwarf2_frame_this_id,
diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c
index b19e95d35090..0fef2c1540e6 100644
--- a/gdb/frame-unwind.c
+++ b/gdb/frame-unwind.c
@@ -127,10 +127,13 @@ frame_unwind_try_unwinder (struct frame_info *this_frame, void **this_cache,
 
   try
     {
+      frame_debug_printf ("trying unwinder \"%s\"", unwinder->name);
       res = unwinder->sniffer (unwinder, this_frame, this_cache);
     }
   catch (const gdb_exception &ex)
     {
+      frame_debug_printf ("caught exception: %s", ex.message->c_str ());
+
       /* Catch all exceptions, caused by either interrupt or error.
 	 Reset *THIS_CACHE, unless something reinitialized the frame
 	 cache meanwhile, in which case THIS_FRAME/THIS_CACHE are now
@@ -153,9 +156,13 @@ frame_unwind_try_unwinder (struct frame_info *this_frame, void **this_cache,
     }
 
   if (res)
-    return 1;
+    {
+      frame_debug_printf ("yes");
+      return 1;
+    }
   else
     {
+      frame_debug_printf ("no");
       /* Don't set *THIS_CACHE to NULL here, because sniffer has to do
 	 so.  */
       frame_cleanup_after_sniffer (this_frame);
@@ -171,6 +178,8 @@ frame_unwind_try_unwinder (struct frame_info *this_frame, void **this_cache,
 void
 frame_unwind_find_by_frame (struct frame_info *this_frame, void **this_cache)
 {
+  frame_debug_printf ("this_frame=%d", frame_relative_level (this_frame));
+
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   struct frame_unwind_table *table
     = (struct frame_unwind_table *) gdbarch_data (gdbarch, frame_unwind_data);
diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h
index da0b4bcbe30f..e46c7ff018b1 100644
--- a/gdb/frame-unwind.h
+++ b/gdb/frame-unwind.h
@@ -158,6 +158,7 @@ typedef struct gdbarch *(frame_prev_arch_ftype) (struct frame_info *this_frame,
 
 struct frame_unwind
 {
+  const char *name;
   /* The frame's type.  Should this instead be a collection of
      predicates that test the frame for various attributes?  */
   enum frame_type type;
diff --git a/gdb/frv-linux-tdep.c b/gdb/frv-linux-tdep.c
index 098df173c087..1f382157ecf7 100644
--- a/gdb/frv-linux-tdep.c
+++ b/gdb/frv-linux-tdep.c
@@ -334,6 +334,7 @@ frv_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind frv_linux_sigtramp_frame_unwind =
 {
+  "frv linux sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   frv_linux_sigtramp_frame_this_id,
diff --git a/gdb/frv-tdep.c b/gdb/frv-tdep.c
index f5edfc72ce3e..ead4488e1463 100644
--- a/gdb/frv-tdep.c
+++ b/gdb/frv-tdep.c
@@ -1411,6 +1411,7 @@ frv_frame_prev_register (struct frame_info *this_frame,
 }
 
 static const struct frame_unwind frv_frame_unwind = {
+  "frv prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   frv_frame_this_id,
diff --git a/gdb/ft32-tdep.c b/gdb/ft32-tdep.c
index 2d8ffea3f84e..ff03acb4cbb4 100644
--- a/gdb/ft32-tdep.c
+++ b/gdb/ft32-tdep.c
@@ -525,6 +525,7 @@ ft32_frame_prev_register (struct frame_info *this_frame,
 
 static const struct frame_unwind ft32_frame_unwind =
 {
+  "ft32 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   ft32_frame_this_id,
diff --git a/gdb/h8300-tdep.c b/gdb/h8300-tdep.c
index 2afe970d0122..7d4495f6646b 100644
--- a/gdb/h8300-tdep.c
+++ b/gdb/h8300-tdep.c
@@ -501,6 +501,7 @@ h8300_frame_prev_register (struct frame_info *this_frame, void **this_cache,
 }
 
 static const struct frame_unwind h8300_frame_unwind = {
+  "h8300 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   h8300_frame_this_id,
diff --git a/gdb/hppa-linux-tdep.c b/gdb/hppa-linux-tdep.c
index a4d1ceeeeb86..5dfea35526c8 100644
--- a/gdb/hppa-linux-tdep.c
+++ b/gdb/hppa-linux-tdep.c
@@ -309,6 +309,7 @@ hppa_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
 }
 
 static const struct frame_unwind hppa_linux_sigtramp_frame_unwind = {
+  "hppa linux sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   hppa_linux_sigtramp_frame_this_id,
diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c
index 21e58f3c3926..63671f3af000 100644
--- a/gdb/hppa-tdep.c
+++ b/gdb/hppa-tdep.c
@@ -2306,6 +2306,7 @@ hppa_frame_unwind_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind hppa_frame_unwind =
 {
+  "hppa unwind table",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   hppa_frame_this_id,
@@ -2418,6 +2419,7 @@ hppa_fallback_frame_prev_register (struct frame_info *this_frame,
 
 static const struct frame_unwind hppa_fallback_frame_unwind =
 {
+  "hppa prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   hppa_fallback_frame_this_id,
@@ -2498,6 +2500,7 @@ hppa_stub_unwind_sniffer (const struct frame_unwind *self,
 }
 
 static const struct frame_unwind hppa_stub_frame_unwind = {
+  "hppa stub",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   hppa_stub_frame_this_id,
diff --git a/gdb/i386-obsd-tdep.c b/gdb/i386-obsd-tdep.c
index 387863f859a9..3f5606df0064 100644
--- a/gdb/i386-obsd-tdep.c
+++ b/gdb/i386-obsd-tdep.c
@@ -391,6 +391,7 @@ i386obsd_trapframe_sniffer (const struct frame_unwind *self,
 }
 
 static const struct frame_unwind i386obsd_trapframe_unwind = {
+  "i386 openbsd trap",
   /* FIXME: kettenis/20051219: This really is more like an interrupt
      frame, but SIGTRAMP_FRAME would print <signal handler called>,
      which really is not what we want here.  */
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 973085ef3370..e436437c6832 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -2196,6 +2196,7 @@ i386_frame_prev_register (struct frame_info *this_frame, void **this_cache,
 
 static const struct frame_unwind i386_frame_unwind =
 {
+  "i386 prologue",
   NORMAL_FRAME,
   i386_frame_unwind_stop_reason,
   i386_frame_this_id,
@@ -2317,6 +2318,7 @@ i386_epilogue_frame_prev_register (struct frame_info *this_frame,
 
 static const struct frame_unwind i386_epilogue_frame_unwind =
 {
+  "i386 epilogue",
   NORMAL_FRAME,
   i386_epilogue_frame_unwind_stop_reason,
   i386_epilogue_frame_this_id,
@@ -2398,6 +2400,7 @@ i386_stack_tramp_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind i386_stack_tramp_frame_unwind =
 {
+  "i386 stack tramp",
   NORMAL_FRAME,
   i386_epilogue_frame_unwind_stop_reason,
   i386_epilogue_frame_this_id,
@@ -2545,6 +2548,7 @@ i386_sigtramp_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind i386_sigtramp_frame_unwind =
 {
+  "i386 sigtramp",
   SIGTRAMP_FRAME,
   i386_sigtramp_frame_unwind_stop_reason,
   i386_sigtramp_frame_this_id,
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index 1c4fc4cca47a..8fa7f8109689 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -2161,6 +2161,7 @@ ia64_frame_prev_register (struct frame_info *this_frame, void **this_cache,
  
 static const struct frame_unwind ia64_frame_unwind =
 {
+  "ia64 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   &ia64_frame_this_id,
@@ -2348,6 +2349,7 @@ ia64_sigtramp_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind ia64_sigtramp_frame_unwind =
 {
+  "ia64 sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   ia64_sigtramp_frame_this_id,
@@ -3006,6 +3008,7 @@ ia64_libunwind_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind ia64_libunwind_frame_unwind =
 {
+  "ia64 libunwind",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   ia64_libunwind_frame_this_id,
@@ -3094,6 +3097,7 @@ ia64_libunwind_sigtramp_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind ia64_libunwind_sigtramp_frame_unwind =
 {
+  "ia64 libunwind sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   ia64_libunwind_sigtramp_frame_this_id,
diff --git a/gdb/inline-frame.c b/gdb/inline-frame.c
index 5ee94af71438..c98af1842a6c 100644
--- a/gdb/inline-frame.c
+++ b/gdb/inline-frame.c
@@ -263,6 +263,7 @@ inline_frame_sniffer (const struct frame_unwind *self,
 }
 
 const struct frame_unwind inline_frame_unwind = {
+  "inline",
   INLINE_FRAME,
   default_frame_unwind_stop_reason,
   inline_frame_this_id,
diff --git a/gdb/iq2000-tdep.c b/gdb/iq2000-tdep.c
index 7ec146993ab8..69bc75860e42 100644
--- a/gdb/iq2000-tdep.c
+++ b/gdb/iq2000-tdep.c
@@ -426,6 +426,7 @@ iq2000_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static const struct frame_unwind iq2000_frame_unwind = {
+  "iq2000 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   iq2000_frame_this_id,
diff --git a/gdb/jit.c b/gdb/jit.c
index 1de785b8de08..b3c52c02eeea 100644
--- a/gdb/jit.c
+++ b/gdb/jit.c
@@ -1048,6 +1048,7 @@ jit_frame_prev_register (struct frame_info *this_frame, void **cache, int reg)
 
 static const struct frame_unwind jit_frame_unwind =
 {
+  "jit",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   jit_frame_this_id,
diff --git a/gdb/lm32-tdep.c b/gdb/lm32-tdep.c
index 6fed69610255..123a1a9fa9af 100644
--- a/gdb/lm32-tdep.c
+++ b/gdb/lm32-tdep.c
@@ -455,6 +455,7 @@ lm32_frame_prev_register (struct frame_info *this_frame,
 }
 
 static const struct frame_unwind lm32_frame_unwind = {
+  "lm32 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   lm32_frame_this_id,
diff --git a/gdb/m32c-tdep.c b/gdb/m32c-tdep.c
index 109551458893..550a63da7569 100644
--- a/gdb/m32c-tdep.c
+++ b/gdb/m32c-tdep.c
@@ -1935,6 +1935,7 @@ m32c_prev_register (struct frame_info *this_frame,
 
 
 static const struct frame_unwind m32c_unwind = {
+  "m32c prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   m32c_this_id,
diff --git a/gdb/m32r-linux-tdep.c b/gdb/m32r-linux-tdep.c
index 1d42a0a43fdf..24807de0b2b0 100644
--- a/gdb/m32r-linux-tdep.c
+++ b/gdb/m32r-linux-tdep.c
@@ -302,6 +302,7 @@ m32r_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
 }
 
 static const struct frame_unwind m32r_linux_sigtramp_frame_unwind = {
+  "m32r linux sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   m32r_linux_sigtramp_frame_this_id,
diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c
index e504f371d755..b5839bebf96a 100644
--- a/gdb/m32r-tdep.c
+++ b/gdb/m32r-tdep.c
@@ -835,6 +835,7 @@ m32r_frame_prev_register (struct frame_info *this_frame,
 }
 
 static const struct frame_unwind m32r_frame_unwind = {
+  "m32r prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   m32r_frame_this_id,
diff --git a/gdb/m68hc11-tdep.c b/gdb/m68hc11-tdep.c
index 4a1d077b7d85..c141711cc87d 100644
--- a/gdb/m68hc11-tdep.c
+++ b/gdb/m68hc11-tdep.c
@@ -924,6 +924,7 @@ m68hc11_frame_prev_register (struct frame_info *this_frame,
 }
 
 static const struct frame_unwind m68hc11_frame_unwind = {
+  "m68hc11 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   m68hc11_frame_this_id,
diff --git a/gdb/m68k-linux-tdep.c b/gdb/m68k-linux-tdep.c
index c72f4851b4c5..7543a35e6112 100644
--- a/gdb/m68k-linux-tdep.c
+++ b/gdb/m68k-linux-tdep.c
@@ -316,6 +316,7 @@ m68k_linux_sigtramp_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind m68k_linux_sigtramp_frame_unwind =
 {
+  "m68k linux sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   m68k_linux_sigtramp_frame_this_id,
diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c
index 76cc38bd6ff0..7397e622f4d8 100644
--- a/gdb/m68k-tdep.c
+++ b/gdb/m68k-tdep.c
@@ -1003,6 +1003,7 @@ m68k_frame_prev_register (struct frame_info *this_frame, void **this_cache,
 
 static const struct frame_unwind m68k_frame_unwind =
 {
+  "m68k prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   m68k_frame_this_id,
diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c
index 0dcfa48d67c1..89fde0abd7db 100644
--- a/gdb/mep-tdep.c
+++ b/gdb/mep-tdep.c
@@ -2053,6 +2053,7 @@ mep_frame_prev_register (struct frame_info *this_frame,
 
 
 static const struct frame_unwind mep_frame_unwind = {
+  "mep prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   mep_frame_this_id,
diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
index 5419dd329c5a..0c3316dece13 100644
--- a/gdb/microblaze-tdep.c
+++ b/gdb/microblaze-tdep.c
@@ -492,6 +492,7 @@ microblaze_frame_prev_register (struct frame_info *this_frame,
 
 static const struct frame_unwind microblaze_frame_unwind =
 {
+  "microblaze prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   microblaze_frame_this_id,
diff --git a/gdb/mips-sde-tdep.c b/gdb/mips-sde-tdep.c
index f08dff4b082e..63cac483b099 100644
--- a/gdb/mips-sde-tdep.c
+++ b/gdb/mips-sde-tdep.c
@@ -164,6 +164,7 @@ mips_sde_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind mips_sde_frame_unwind =
 {
+  "mips sde sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   mips_sde_frame_this_id,
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 2aee4f10b316..f16cdaa14ccb 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -2901,6 +2901,7 @@ mips_insn16_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind mips_insn16_frame_unwind =
 {
+  "mips insn16 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   mips_insn16_frame_this_id,
@@ -3336,6 +3337,7 @@ mips_micro_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind mips_micro_frame_unwind =
 {
+  "mips micro prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   mips_micro_frame_this_id,
@@ -3711,6 +3713,7 @@ mips_insn32_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind mips_insn32_frame_unwind =
 {
+  "mips insn32 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   mips_insn32_frame_this_id,
@@ -3827,6 +3830,7 @@ mips_stub_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind mips_stub_frame_unwind =
 {
+  "mips stub",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   mips_stub_frame_this_id,
diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c
index cefd547af529..2961f2afde1f 100644
--- a/gdb/mn10300-tdep.c
+++ b/gdb/mn10300-tdep.c
@@ -1132,6 +1132,7 @@ mn10300_frame_prev_register (struct frame_info *this_frame,
 }
 
 static const struct frame_unwind mn10300_frame_unwind = {
+  "mn10300 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   mn10300_frame_this_id, 
diff --git a/gdb/moxie-tdep.c b/gdb/moxie-tdep.c
index 9af37d65cc59..c48f9f75eb4e 100644
--- a/gdb/moxie-tdep.c
+++ b/gdb/moxie-tdep.c
@@ -587,6 +587,7 @@ moxie_frame_prev_register (struct frame_info *this_frame,
 }
 
 static const struct frame_unwind moxie_frame_unwind = {
+  "moxie prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   moxie_frame_this_id,
diff --git a/gdb/msp430-tdep.c b/gdb/msp430-tdep.c
index 7fa4475aa2c2..06a468ca85c6 100644
--- a/gdb/msp430-tdep.c
+++ b/gdb/msp430-tdep.c
@@ -538,6 +538,7 @@ msp430_prev_register (struct frame_info *this_frame,
 }
 
 static const struct frame_unwind msp430_unwind = {
+  "msp430 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   msp430_this_id,
diff --git a/gdb/nds32-tdep.c b/gdb/nds32-tdep.c
index e30a016c5e33..36f4979c042c 100644
--- a/gdb/nds32-tdep.c
+++ b/gdb/nds32-tdep.c
@@ -997,6 +997,7 @@ nds32_frame_prev_register (struct frame_info *this_frame, void **this_cache,
 
 static const struct frame_unwind nds32_frame_unwind =
 {
+  "nds32 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   nds32_frame_this_id,
@@ -1380,6 +1381,7 @@ nds32_epilogue_frame_prev_register (struct frame_info *this_frame,
 
 static const struct frame_unwind nds32_epilogue_frame_unwind =
 {
+  "nds32 epilogue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   nds32_epilogue_frame_this_id,
diff --git a/gdb/nios2-tdep.c b/gdb/nios2-tdep.c
index 8fd3695da2d2..b090680a7afc 100644
--- a/gdb/nios2-tdep.c
+++ b/gdb/nios2-tdep.c
@@ -1979,6 +1979,7 @@ nios2_frame_base_address (struct frame_info *this_frame, void **this_cache)
 
 static const struct frame_unwind nios2_frame_unwind =
 {
+  "nios2 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   nios2_frame_this_id,
@@ -2079,6 +2080,7 @@ nios2_stub_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind nios2_stub_frame_unwind =
 {
+  "nios2 stub",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   nios2_stub_frame_this_id,
diff --git a/gdb/or1k-tdep.c b/gdb/or1k-tdep.c
index db6c41b32f25..91f21576bd53 100644
--- a/gdb/or1k-tdep.c
+++ b/gdb/or1k-tdep.c
@@ -1096,6 +1096,7 @@ or1k_frame_prev_register (struct frame_info *this_frame,
 /* Data structures for the normal prologue-analysis-based unwinder.  */
 
 static const struct frame_unwind or1k_frame_unwind = {
+  "or1k prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   or1k_frame_this_id,
diff --git a/gdb/ppc-fbsd-tdep.c b/gdb/ppc-fbsd-tdep.c
index d03df9666fc4..f41c8bb0be92 100644
--- a/gdb/ppc-fbsd-tdep.c
+++ b/gdb/ppc-fbsd-tdep.c
@@ -263,6 +263,7 @@ ppcfbsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
 }
 
 static const struct frame_unwind ppcfbsd_sigtramp_frame_unwind = {
+  "ppc freebsd sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   ppcfbsd_sigtramp_frame_this_id,
diff --git a/gdb/ppc-obsd-tdep.c b/gdb/ppc-obsd-tdep.c
index b92f11c67ec1..98b3e4013e9a 100644
--- a/gdb/ppc-obsd-tdep.c
+++ b/gdb/ppc-obsd-tdep.c
@@ -232,6 +232,7 @@ ppcobsd_sigtramp_frame_prev_register (struct frame_info *this_frame,
 }
 
 static const struct frame_unwind ppcobsd_sigtramp_frame_unwind = {
+  "ppc openbsd sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   ppcobsd_sigtramp_frame_this_id,
diff --git a/gdb/python/py-unwind.c b/gdb/python/py-unwind.c
index 18ea2434f87e..3d87a1908460 100644
--- a/gdb/python/py-unwind.c
+++ b/gdb/python/py-unwind.c
@@ -680,6 +680,7 @@ pyuw_on_new_gdbarch (struct gdbarch *newarch)
       struct frame_unwind *unwinder
 	  = GDBARCH_OBSTACK_ZALLOC (newarch, struct frame_unwind);
 
+      unwinder->name = "python";
       unwinder->type = NORMAL_FRAME;
       unwinder->stop_reason = default_frame_unwind_stop_reason;
       unwinder->this_id = pyuw_this_id;
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 00affb85d22e..bf899ebeb246 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -1889,6 +1889,7 @@ record_btrace_frame_dealloc_cache (struct frame_info *self, void *this_cache)
 
 const struct frame_unwind record_btrace_frame_unwind =
 {
+  "record-btrace",
   NORMAL_FRAME,
   record_btrace_frame_unwind_stop_reason,
   record_btrace_frame_this_id,
@@ -1900,6 +1901,7 @@ const struct frame_unwind record_btrace_frame_unwind =
 
 const struct frame_unwind record_btrace_tailcall_frame_unwind =
 {
+  "record-btrace tailcall",
   TAILCALL_FRAME,
   record_btrace_frame_unwind_stop_reason,
   record_btrace_frame_this_id,
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index d942b059f55b..19e2616c9c0e 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -3320,6 +3320,7 @@ riscv_frame_prev_register (struct frame_info *this_frame,
 
 static const struct frame_unwind riscv_frame_unwind =
 {
+  /*.name          =*/ "riscv prologue",
   /*.type          =*/ NORMAL_FRAME,
   /*.stop_reason   =*/ default_frame_unwind_stop_reason,
   /*.this_id       =*/ riscv_frame_this_id,
diff --git a/gdb/rl78-tdep.c b/gdb/rl78-tdep.c
index c9394b235e97..1c4829f68dfd 100644
--- a/gdb/rl78-tdep.c
+++ b/gdb/rl78-tdep.c
@@ -1183,6 +1183,7 @@ rl78_prev_register (struct frame_info *this_frame,
 
 static const struct frame_unwind rl78_unwind =
 {
+  "rl78 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   rl78_this_id,
diff --git a/gdb/rs6000-aix-tdep.c b/gdb/rs6000-aix-tdep.c
index 02d492b33771..3717f2b4b2aa 100644
--- a/gdb/rs6000-aix-tdep.c
+++ b/gdb/rs6000-aix-tdep.c
@@ -156,6 +156,7 @@ aix_sighandle_frame_sniffer (const struct frame_unwind *self,
 /* AIX signal handler frame unwinder */
 
 static const struct frame_unwind aix_sighandle_frame_unwind = {
+  "rs6000 aix sighandle",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   aix_sighandle_frame_this_id,
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index a629450d746f..826f0266ed84 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -3783,6 +3783,7 @@ rs6000_frame_prev_register (struct frame_info *this_frame,
 
 static const struct frame_unwind rs6000_frame_unwind =
 {
+  "rs6000 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   rs6000_frame_this_id,
@@ -3882,6 +3883,7 @@ rs6000_epilogue_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind rs6000_epilogue_frame_unwind =
 {
+  "rs6000 epilogue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   rs6000_epilogue_frame_this_id, rs6000_epilogue_frame_prev_register,
diff --git a/gdb/rx-tdep.c b/gdb/rx-tdep.c
index 4aaff4e3f5c8..6715e73c3c7a 100644
--- a/gdb/rx-tdep.c
+++ b/gdb/rx-tdep.c
@@ -630,6 +630,7 @@ rx_exception_sniffer (const struct frame_unwind *self,
    analyzer.  */
 
 static const struct frame_unwind rx_frame_unwind = {
+  "rx prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   rx_frame_this_id,
@@ -642,6 +643,7 @@ static const struct frame_unwind rx_frame_unwind = {
    analyzer.  */
 
 static const struct frame_unwind rx_exception_unwind = {
+  "rx exception",
   /* SIGTRAMP_FRAME could be used here, but backtraces are less informative.  */
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
diff --git a/gdb/s12z-tdep.c b/gdb/s12z-tdep.c
index 13615f0abaca..faf63c403054 100644
--- a/gdb/s12z-tdep.c
+++ b/gdb/s12z-tdep.c
@@ -467,6 +467,7 @@ s12z_frame_prev_register (struct frame_info *this_frame,
 
 /* Data structures for the normal prologue-analysis-based unwinder.  */
 static const struct frame_unwind s12z_frame_unwind = {
+  "s12z prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   s12z_frame_this_id,
diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c
index 4a39681f43f8..04a4ff8df34a 100644
--- a/gdb/s390-linux-tdep.c
+++ b/gdb/s390-linux-tdep.c
@@ -542,6 +542,7 @@ s390_sigtramp_frame_sniffer (const struct frame_unwind *self,
 /* S390 sigtramp frame unwinder.  */
 
 static const struct frame_unwind s390_sigtramp_frame_unwind = {
+  "s390 linux sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   s390_sigtramp_frame_this_id,
diff --git a/gdb/s390-tdep.c b/gdb/s390-tdep.c
index 4905bcab36e4..2579ee82b203 100644
--- a/gdb/s390-tdep.c
+++ b/gdb/s390-tdep.c
@@ -2634,6 +2634,7 @@ s390_frame_prev_register (struct frame_info *this_frame,
 /* Default S390 frame unwinder.  */
 
 static const struct frame_unwind s390_frame_unwind = {
+  "s390 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   s390_frame_this_id,
@@ -2727,6 +2728,7 @@ s390_stub_frame_sniffer (const struct frame_unwind *self,
 /* S390 stub frame unwinder.  */
 
 static const struct frame_unwind s390_stub_frame_unwind = {
+  "s390 stub",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   s390_stub_frame_this_id,
diff --git a/gdb/score-tdep.c b/gdb/score-tdep.c
index 531b308749cd..91d79f410647 100644
--- a/gdb/score-tdep.c
+++ b/gdb/score-tdep.c
@@ -1351,6 +1351,7 @@ score_prologue_prev_register (struct frame_info *this_frame,
 
 static const struct frame_unwind score_prologue_unwind =
 {
+  "score prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   score_prologue_this_id,
diff --git a/gdb/sentinel-frame.c b/gdb/sentinel-frame.c
index 8016d0658e32..42ef722f5c68 100644
--- a/gdb/sentinel-frame.c
+++ b/gdb/sentinel-frame.c
@@ -79,6 +79,7 @@ sentinel_frame_prev_arch (struct frame_info *this_frame,
 
 const struct frame_unwind sentinel_frame_unwind =
 {
+  "sentinel",
   SENTINEL_FRAME,
   default_frame_unwind_stop_reason,
   sentinel_frame_this_id,
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index 4dd5d9fbb308..bfb220adf792 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -1968,6 +1968,7 @@ sh_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static const struct frame_unwind sh_frame_unwind = {
+  "sh prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   sh_frame_this_id,
@@ -2034,6 +2035,7 @@ sh_stub_unwind_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind sh_stub_unwind =
 {
+  "sh stub",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   sh_stub_this_id,
diff --git a/gdb/sparc-netbsd-tdep.c b/gdb/sparc-netbsd-tdep.c
index c2de5b544c2e..e34405c849e3 100644
--- a/gdb/sparc-netbsd-tdep.c
+++ b/gdb/sparc-netbsd-tdep.c
@@ -251,6 +251,7 @@ sparc32nbsd_sigcontext_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind sparc32nbsd_sigcontext_frame_unwind =
 {
+  "sparc32 netbsd sigcontext",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   sparc32nbsd_sigcontext_frame_this_id,
diff --git a/gdb/sparc-obsd-tdep.c b/gdb/sparc-obsd-tdep.c
index e198e9702cdb..1215bdd3465d 100644
--- a/gdb/sparc-obsd-tdep.c
+++ b/gdb/sparc-obsd-tdep.c
@@ -136,6 +136,7 @@ sparc32obsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
 }
 static const struct frame_unwind sparc32obsd_sigtramp_frame_unwind =
 {
+  "sparc32 openbsd sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   sparc32obsd_sigtramp_frame_this_id,
diff --git a/gdb/sparc-sol2-tdep.c b/gdb/sparc-sol2-tdep.c
index ce92e7b22e35..f21444937383 100644
--- a/gdb/sparc-sol2-tdep.c
+++ b/gdb/sparc-sol2-tdep.c
@@ -182,6 +182,7 @@ sparc32_sol2_sigtramp_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind sparc32_sol2_sigtramp_frame_unwind =
 {
+  "sparc32 solaris sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   sparc32_sol2_sigtramp_frame_this_id,
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index a6df0fcb58b4..1b42068af192 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -1358,6 +1358,7 @@ sparc32_frame_prev_register (struct frame_info *this_frame,
 
 static const struct frame_unwind sparc32_frame_unwind =
 {
+  "sparc32 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   sparc32_frame_this_id,
diff --git a/gdb/sparc64-fbsd-tdep.c b/gdb/sparc64-fbsd-tdep.c
index 6f906d53173b..6dad813c356c 100644
--- a/gdb/sparc64-fbsd-tdep.c
+++ b/gdb/sparc64-fbsd-tdep.c
@@ -199,6 +199,7 @@ sparc64fbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind sparc64fbsd_sigtramp_frame_unwind =
 {
+  "sparc64 freebsd sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   sparc64fbsd_sigtramp_frame_this_id,
diff --git a/gdb/sparc64-netbsd-tdep.c b/gdb/sparc64-netbsd-tdep.c
index 7fa0c1a29afa..0438093563ee 100644
--- a/gdb/sparc64-netbsd-tdep.c
+++ b/gdb/sparc64-netbsd-tdep.c
@@ -225,6 +225,7 @@ sparc64nbsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind sparc64nbsd_sigcontext_frame_unwind =
 {
+  "sparc64 netbsd sigcontext",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   sparc64nbsd_sigcontext_frame_this_id,
diff --git a/gdb/sparc64-obsd-tdep.c b/gdb/sparc64-obsd-tdep.c
index cf3138a7ab14..033779e273de 100644
--- a/gdb/sparc64-obsd-tdep.c
+++ b/gdb/sparc64-obsd-tdep.c
@@ -222,6 +222,7 @@ sparc64obsd_sigtramp_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind sparc64obsd_frame_unwind =
 {
+  "sparc64 openbsd sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   sparc64obsd_frame_this_id,
@@ -305,6 +306,7 @@ sparc64obsd_trapframe_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind sparc64obsd_trapframe_unwind =
 {
+  "sparc64 openbsd trap",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   sparc64obsd_trapframe_this_id,
diff --git a/gdb/sparc64-sol2-tdep.c b/gdb/sparc64-sol2-tdep.c
index c4293c938e7c..6aea8bd56d7d 100644
--- a/gdb/sparc64-sol2-tdep.c
+++ b/gdb/sparc64-sol2-tdep.c
@@ -185,6 +185,7 @@ sparc64_sol2_sigtramp_frame_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind sparc64_sol2_sigtramp_frame_unwind =
 {
+  "sparc64 solaris sigtramp",
   SIGTRAMP_FRAME,
   default_frame_unwind_stop_reason,
   sparc64_sol2_sigtramp_frame_this_id,
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index 4157594d1533..3464411512e4 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -1141,6 +1141,7 @@ sparc64_frame_prev_register (struct frame_info *this_frame, void **this_cache,
 
 static const struct frame_unwind sparc64_frame_unwind =
 {
+  "sparc64 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   sparc64_frame_this_id,
diff --git a/gdb/tic6x-tdep.c b/gdb/tic6x-tdep.c
index 01dd86c541c4..fb18b798db2f 100644
--- a/gdb/tic6x-tdep.c
+++ b/gdb/tic6x-tdep.c
@@ -457,6 +457,7 @@ tic6x_frame_base_address (struct frame_info *this_frame, void **this_cache)
 
 static const struct frame_unwind tic6x_frame_unwind =
 {
+  "tic6x prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   tic6x_frame_this_id,
@@ -519,6 +520,7 @@ tic6x_stub_unwind_sniffer (const struct frame_unwind *self,
 
 static const struct frame_unwind tic6x_stub_unwind =
 {
+  "tic6x stub",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   tic6x_stub_this_id,
diff --git a/gdb/tilegx-tdep.c b/gdb/tilegx-tdep.c
index 9bd982f49f50..17d27d4c486b 100644
--- a/gdb/tilegx-tdep.c
+++ b/gdb/tilegx-tdep.c
@@ -905,6 +905,7 @@ tilegx_frame_base_address (struct frame_info *this_frame, void **this_cache)
 }
 
 static const struct frame_unwind tilegx_frame_unwind = {
+  "tilegx prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   tilegx_frame_this_id,
diff --git a/gdb/v850-tdep.c b/gdb/v850-tdep.c
index 5114c1bd2d26..8f25198205e9 100644
--- a/gdb/v850-tdep.c
+++ b/gdb/v850-tdep.c
@@ -1320,6 +1320,7 @@ v850_frame_this_id (struct frame_info *this_frame, void **this_cache,
 }
 
 static const struct frame_unwind v850_frame_unwind = {
+  "v850 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   v850_frame_this_id,
diff --git a/gdb/vax-tdep.c b/gdb/vax-tdep.c
index 5e6c65ae4421..249b0bf67730 100644
--- a/gdb/vax-tdep.c
+++ b/gdb/vax-tdep.c
@@ -390,6 +390,7 @@ vax_frame_prev_register (struct frame_info *this_frame,
 
 static const struct frame_unwind vax_frame_unwind =
 {
+  "vax prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   vax_frame_this_id,
diff --git a/gdb/xstormy16-tdep.c b/gdb/xstormy16-tdep.c
index 8a0199cd9eb1..1e9491da9e47 100644
--- a/gdb/xstormy16-tdep.c
+++ b/gdb/xstormy16-tdep.c
@@ -736,6 +736,7 @@ xstormy16_frame_base_address (struct frame_info *this_frame, void **this_cache)
 }
 
 static const struct frame_unwind xstormy16_frame_unwind = {
+  "xstormy16 prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   xstormy16_frame_this_id,
diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c
index 246921253d2b..6862a03ea2be 100644
--- a/gdb/xtensa-tdep.c
+++ b/gdb/xtensa-tdep.c
@@ -1499,6 +1499,7 @@ xtensa_frame_prev_register (struct frame_info *this_frame,
 static const struct frame_unwind
 xtensa_unwind =
 {
+  "xtensa prologue",
   NORMAL_FRAME,
   default_frame_unwind_stop_reason,
   xtensa_frame_this_id,
-- 
2.32.0


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

* [PATCH 5/5] gdb: introduce FRAME_SCOPED_DEBUG_ENTER_EXIT
  2021-06-28 17:44 [PATCH 0/5] Frame debug output improvements Simon Marchi
                   ` (3 preceding siblings ...)
  2021-06-28 17:44 ` [PATCH 4/5] gdb: add names to unwinders, add debug messages when looking for unwinder Simon Marchi
@ 2021-06-28 17:44 ` Simon Marchi
  2021-06-28 19:06 ` [PATCH 0/5] Frame debug output improvements Tom Tromey
  2021-06-29  9:31 ` Andrew Burgess
  6 siblings, 0 replies; 11+ messages in thread
From: Simon Marchi @ 2021-06-28 17:44 UTC (permalink / raw)
  To: gdb-patches

Introduce FRAME_SCOPED_DEBUG_ENTER_EXIT and use it to print enter/exit
messages in important frame-related functions.  I think this helps
understand which lower-level operations are done as part of which
higher-level operation.  And it helps visually skip over a higher-level
operation you are not interested in.

Here's an example, combined with some py-unwind messages:

    [frame] frame_unwind_find_by_frame: enter
      [frame] frame_unwind_find_by_frame: this_frame=0
      [frame] frame_unwind_try_unwinder: trying unwinder "dummy"
      [frame] frame_unwind_try_unwinder: no
      [frame] frame_unwind_try_unwinder: trying unwinder "dwarf2 tailcall"
      [frame] frame_unwind_try_unwinder: no
      [frame] frame_unwind_try_unwinder: trying unwinder "inline"
      [frame] frame_unwind_try_unwinder: no
      [frame] frame_unwind_try_unwinder: trying unwinder "jit"
      [frame] frame_unwind_try_unwinder: no
      [frame] frame_unwind_try_unwinder: trying unwinder "python"
      [py-unwind] pyuw_sniffer: enter
        [frame] frame_unwind_register_value: enter
          [frame] frame_unwind_register_value: frame=-1, regnum=7(rsp)
          [frame] frame_unwind_register_value:   -> register=7 bytes=[40ddffffff7f0000]
        [frame] frame_unwind_register_value: exit
        [py-unwind] pyuw_sniffer: frame=0, sp=0x7fffffffdd40, pc=0x5555555551ec
        [frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
        [frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
        [frame] frame_id_eq: l={stack=<sentinel>,!code,special=0x0000000000000000}, r={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
        [frame] frame_unwind_register_value: enter
          [frame] frame_unwind_register_value: frame=-1, regnum=6(rbp)
          [frame] frame_unwind_register_value:   -> register=6 bytes=[50ddffffff7f0000]
        [frame] frame_unwind_register_value: exit
        [frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
        [frame] frame_id_eq: l={stack=<sentinel>,!code,special=0x0000000000000000}, r={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
        [frame] get_prev_frame: enter
          [frame] get_prev_frame_always_1: enter
            [frame] get_prev_frame_always_1: this_frame=-1
            [frame] get_prev_frame_always_1:   -> {level=0,type=NORMAL_FRAME,unwind=0x5588ee3d17c0,pc=0x5555555551ec,id=<not computed>,func=<unknown>} // cached
          [frame] get_prev_frame_always_1: exit
        [frame] get_prev_frame: exit
        [frame] value_fetch_lazy_register: (frame=0, regnum=6(rbp), ...) -> register=6 bytes=[50ddffffff7f0000]
        [frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
        [frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
        [frame] frame_id_eq: l={stack=<sentinel>,!code,special=0x0000000000000000}, r={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
        [frame] frame_unwind_register_value: enter
          [frame] frame_unwind_register_value: frame=-1, regnum=7(rsp)
          [frame] frame_unwind_register_value:   -> register=7 bytes=[40ddffffff7f0000]
        [frame] frame_unwind_register_value: exit
        [frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
        [frame] frame_id_eq: l={stack=<sentinel>,!code,special=0x0000000000000000}, r={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
        [frame] get_prev_frame: enter
          [frame] get_prev_frame_always_1: enter
            [frame] get_prev_frame_always_1: this_frame=-1
            [frame] get_prev_frame_always_1:   -> {level=0,type=NORMAL_FRAME,unwind=0x5588ee3d1824,pc=0x5555555551ec,id=<not computed>,func=<unknown>} // cached
          [frame] get_prev_frame_always_1: exit
        [frame] get_prev_frame: exit
        [frame] value_fetch_lazy_register: (frame=0, regnum=7(rsp), ...) -> register=7 bytes=[40ddffffff7f0000]
        [frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
        [frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
        [frame] frame_id_eq: l={stack=<sentinel>,!code,special=0x0000000000000000}, r={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
        [frame] frame_unwind_register_value: enter
          [frame] frame_unwind_register_value: frame=-1, regnum=16(rip)
          [frame] frame_unwind_register_value:   -> register=16 bytes=[ec51555555550000]
        [frame] frame_unwind_register_value: exit
        [frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
        [frame] frame_id_eq: l={stack=<sentinel>,!code,special=0x0000000000000000}, r={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
        [frame] get_prev_frame: enter
          [frame] get_prev_frame_always_1: enter
            [frame] get_prev_frame_always_1: this_frame=-1
            [frame] get_prev_frame_always_1:   -> {level=0,type=NORMAL_FRAME,unwind=0x5588ee3d1888,pc=0x5555555551ec,id=<not computed>,func=<unknown>} // cached
          [frame] get_prev_frame_always_1: exit
        [frame] get_prev_frame: exit
        [frame] value_fetch_lazy_register: (frame=0, regnum=16(rip), ...) -> register=16 bytes=[ec51555555550000]
        [py-unwind] pyuw_sniffer: frame claimed by unwinder test unwinder
      [py-unwind] pyuw_sniffer: exit
      [frame] frame_unwind_try_unwinder: yes
    [frame] frame_unwind_find_by_frame: exit

gdb/ChangeLog:

	* frame.h (FRAME_SCOPED_DEBUG_ENTER_EXIT): New.
	* frame.c (compute_frame_id, get_prev_frame_always_1,
	get_prev_frame): Use FRAME_SCOPED_DEBUG_ENTER_EXIT.
	* frame-unwind.c (frame_unwind_find_by_frame): Likewise.
	(frame_unwind_register_value): Likewise.

Change-Id: I45b69b4ed962e70572bc55b8adfb211483c1eeed
---
 gdb/frame-unwind.c                            |  1 +
 gdb/frame.c                                   | 21 +++++++++++--------
 gdb/frame.h                                   |  6 ++++++
 .../gdb.dwarf2/dw2-reg-undefined.exp          |  4 ++--
 4 files changed, 21 insertions(+), 11 deletions(-)

diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c
index 0fef2c1540e6..3dc303a49ad5 100644
--- a/gdb/frame-unwind.c
+++ b/gdb/frame-unwind.c
@@ -178,6 +178,7 @@ frame_unwind_try_unwinder (struct frame_info *this_frame, void **this_cache,
 void
 frame_unwind_find_by_frame (struct frame_info *this_frame, void **this_cache)
 {
+  FRAME_SCOPED_DEBUG_ENTER_EXIT;
   frame_debug_printf ("this_frame=%d", frame_relative_level (this_frame));
 
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
diff --git a/gdb/frame.c b/gdb/frame.c
index 7b459680313a..3f2d2700541c 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -560,6 +560,8 @@ skip_tailcall_frames (struct frame_info *frame)
 static void
 compute_frame_id (struct frame_info *fi)
 {
+  FRAME_SCOPED_DEBUG_ENTER_EXIT;
+
   gdb_assert (fi->this_id.p == frame_id_status::NOT_COMPUTED);
 
   unsigned int entry_generation = get_frame_cache_generation ();
@@ -1215,12 +1217,10 @@ get_frame_register (struct frame_info *frame,
 struct value *
 frame_unwind_register_value (frame_info *next_frame, int regnum)
 {
-  struct gdbarch *gdbarch;
-  struct value *value;
+  FRAME_SCOPED_DEBUG_ENTER_EXIT;
 
   gdb_assert (next_frame != NULL);
-  gdbarch = frame_unwind_arch (next_frame);
-
+  gdbarch *gdbarch = frame_unwind_arch (next_frame);
   frame_debug_printf ("frame=%d, regnum=%d(%s)",
 		      next_frame->level, regnum,
 		      user_reg_map_regnum_to_name (gdbarch, regnum));
@@ -1230,9 +1230,9 @@ frame_unwind_register_value (frame_info *next_frame, int regnum)
     frame_unwind_find_by_frame (next_frame, &next_frame->prologue_cache);
 
   /* Ask this frame to unwind its register.  */
-  value = next_frame->unwind->prev_register (next_frame,
-					     &next_frame->prologue_cache,
-					     regnum);
+  value *value = next_frame->unwind->prev_register (next_frame,
+						    &next_frame->prologue_cache,
+						    regnum);
 
   if (frame_debug)
     {
@@ -2104,10 +2104,9 @@ get_prev_frame_if_no_cycle (struct frame_info *this_frame)
 static struct frame_info *
 get_prev_frame_always_1 (struct frame_info *this_frame)
 {
-  struct gdbarch *gdbarch;
+  FRAME_SCOPED_DEBUG_ENTER_EXIT;
 
   gdb_assert (this_frame != NULL);
-  gdbarch = get_frame_arch (this_frame);
 
   if (frame_debug)
     {
@@ -2117,6 +2116,8 @@ get_prev_frame_always_1 (struct frame_info *this_frame)
 	frame_debug_printf ("this_frame=nullptr");
     }
 
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+
   /* Only try to do the unwind once.  */
   if (this_frame->prev_p)
     {
@@ -2419,6 +2420,8 @@ inside_entry_func (frame_info *this_frame)
 struct frame_info *
 get_prev_frame (struct frame_info *this_frame)
 {
+  FRAME_SCOPED_DEBUG_ENTER_EXIT;
+
   CORE_ADDR frame_pc;
   int frame_pc_p;
 
diff --git a/gdb/frame.h b/gdb/frame.h
index f8314ad66ceb..0d2bc08a47bf 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -71,6 +71,7 @@
 
 #include "language.h"
 #include "cli/cli-option.h"
+#include "gdbsupport/common-debug.h"
 
 struct symtab_and_line;
 struct frame_unwind;
@@ -221,6 +222,11 @@ extern bool frame_debug;
 #define frame_debug_printf(fmt, ...) \
   debug_prefixed_printf_cond (frame_debug, "frame", fmt, ##__VA_ARGS__)
 
+/* Print "frame" enter/exit debug statements.  */
+
+#define FRAME_SCOPED_DEBUG_ENTER_EXIT \
+  scoped_debug_enter_exit (frame_debug, "frame")
+
 /* Construct a frame ID.  The first parameter is the frame's constant
    stack address (typically the outer-bound), and the second the
    frame's constant code address (typically the entry point).
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.exp b/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.exp
index 2473a41a0de0..b1c28b2f41c6 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-reg-undefined.exp
@@ -79,8 +79,8 @@ for {set f 0} {$f < 3} {incr f} {
 # "not saved" and not "optimized out".
 gdb_test "set debug frame 1"
 gdb_test {print $rax} [multi_line \
-			{\[frame\] frame_unwind_register_value: frame=0, regnum=0\(rax\)} \
-			{\[frame\] frame_unwind_register_value:   -> <not saved>} \
+			{    \[frame\] frame_unwind_register_value: frame=0, regnum=0\(rax\)} \
+			{    \[frame\] frame_unwind_register_value:   -> <not saved>} \
 			{.*}]
 gdb_test "set debug frame 0"
 
-- 
2.32.0


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

* Re: [PATCH 0/5] Frame debug output improvements
  2021-06-28 17:44 [PATCH 0/5] Frame debug output improvements Simon Marchi
                   ` (4 preceding siblings ...)
  2021-06-28 17:44 ` [PATCH 5/5] gdb: introduce FRAME_SCOPED_DEBUG_ENTER_EXIT Simon Marchi
@ 2021-06-28 19:06 ` Tom Tromey
  2021-06-29  9:31 ` Andrew Burgess
  6 siblings, 0 replies; 11+ messages in thread
From: Tom Tromey @ 2021-06-28 19:06 UTC (permalink / raw)
  To: Simon Marchi via Gdb-patches

>>>>> "Simon" == Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> writes:

Simon> I started improving the frame debug messages a while ago, while helping
Simon> Eli figure out why GDB couldn't unwind past a JIT frame.  I've been
Simon> sitting on these changes since, and finally cleaned them up for
Simon> submission.

These look reasonable to me.
I've wanted patch #4 several times now...

Tom

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

* Re: [PATCH 2/5] gdb: value_fetch_lazy_register: fix getting frame id while it is computed
  2021-06-28 17:44 ` [PATCH 2/5] gdb: value_fetch_lazy_register: fix getting frame id while it is computed Simon Marchi
@ 2021-06-29  9:27   ` Andrew Burgess
  2021-06-29 14:53     ` Simon Marchi
  0 siblings, 1 reply; 11+ messages in thread
From: Andrew Burgess @ 2021-06-29  9:27 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

* Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> [2021-06-28 13:44:26 -0400]:

> This gives an internal error:
> 
>     $ ./gdb -q -nx --data-directory=data-directory  -q testsuite/outputs/gdb.python/py-unwind/py-unwind -x /home/simark/src/binutils-gdb/gdb/testsuite/gdb.python/py-unwind.py -ex "set debug frame 1" -ex r
>     ...
>     /home/simark/src/binutils-gdb/gdb/frame.c:623: internal-error: frame_id get_frame_id(frame_info*): Assertion `fi->this_id.p != frame_id_status::COMPUTING' failed.
> 
> The backtrace is:
> 
>     #9  0x000055d0b48e294a in internal_error (file=0x55d0b4c71380 "/home/simark/src/binutils-gdb/gdb/frame.c", line=623, fmt=0x55d0b4c712a0 "%s: Assertion `%s' failed.") at /home/simark/src/binutils-gdb/gdbsupport/errors.cc:55
>     #10 0x000055d0b28aade3 in get_frame_id (fi=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/frame.c:623
>     #11 0x000055d0b28b5350 in get_prev_frame_id_by_id (id=<error reading variable: Cannot access memory at address 0xfffffffffffffd9c>) at /home/simark/src/binutils-gdb/gdb/frame.c:2601
>     #12 0x000055d0b375a1ab in value_fetch_lazy_register (val=0x6110000b3500) at /home/simark/src/binutils-gdb/gdb/value.c:3955
>     #13 0x000055d0b375a9e7 in value_fetch_lazy (val=0x6110000b3500) at /home/simark/src/binutils-gdb/gdb/value.c:4024
>     #14 0x000055d0b28a0548 in value_of_register (regnum=6, frame=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/findvar.c:274
>     #15 0x000055d0b301b05a in pending_framepy_read_register (self=0x7f79056bb7f0, args=0x7f790581aa90) at /home/simark/src/binutils-gdb/gdb/python/py-unwind.c:398
>     <some Python frames>
>     #27 0x000055d0b301c6b4 in pyuw_sniffer (self=0x62100018e250, this_frame=0x6210001ff5e0, cache_ptr=0x6210001ff5f8) at /home/simark/src/binutils-gdb/gdb/python/py-unwind.c:568
>     #28 0x000055d0b28a6587 in frame_unwind_try_unwinder (this_frame=0x6210001ff5e0, this_cache=0x6210001ff5f8, unwinder=0x62100018e250) at /home/simark/src/binutils-gdb/gdb/frame-unwind.c:130
>     #29 0x000055d0b28a67b5 in frame_unwind_find_by_frame (this_frame=0x6210001ff5e0, this_cache=0x6210001ff5f8) at /home/simark/src/binutils-gdb/gdb/frame-unwind.c:193
>     #30 0x000055d0b28aa80f in compute_frame_id (fi=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/frame.c:585
>     #31 0x000055d0b28aaeae in get_frame_id (fi=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/frame.c:635
>     #32 0x000055d0b28b5350 in get_prev_frame_id_by_id (id=<error reading variable: Cannot access memory at address 0xfffffffffffffd9c>) at /home/simark/src/binutils-gdb/gdb/frame.c:2601
>     #33 0x000055d0b375a1ab in value_fetch_lazy_register (val=0x6110000b3280) at /home/simark/src/binutils-gdb/gdb/value.c:3955
>     #34 0x000055d0b375a9e7 in value_fetch_lazy (val=0x6110000b3280) at /home/simark/src/binutils-gdb/gdb/value.c:4024
>     #35 0x000055d0b28a0548 in value_of_register (regnum=1, frame=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/findvar.c:274
>     #36 0x000055d0b2826b1c in eval_op_register (expect_type=0x6210001949f0, exp=0x6030000d6840, noside=EVAL_NORMAL, name=0x60400003e2e8 "rbx") at /home/simark/src/binutils-gdb/gdb/eval.c:1074
>     #37 0x000055d0b218139f in expr::register_operation::evaluate (this=0x60400003e2d0, expect_type=0x6210001949f0, exp=0x6030000d6840, noside=EVAL_NORMAL) at /home/simark/src/binutils-gdb/gdb/expop.h:830
>     #38 0x000055d0b282f5d5 in expr::operation::evaluate_for_cast (this=0x60400003e2d0, expect_type=0x6210001949f0, exp=0x6030000d6840, noside=EVAL_NORMAL) at /home/simark/src/binutils-gdb/gdb/eval.c:2506
>     #39 0x000055d0b2181c64 in expr::unop_cast_operation::evaluate (this=0x6030000d6870, expect_type=0x6210001949f0, exp=0x6030000d6840, noside=EVAL_NORMAL) at /home/simark/src/binutils-gdb/gdb/expop.h:1975
>     #40 0x000055d0b2820b04 in expression::evaluate (this=0x6030000d6840, expect_type=0x6210001949f0, noside=EVAL_NORMAL) at /home/simark/src/binutils-gdb/gdb/eval.c:101
>     #41 0x000055d0b2820c46 in evaluate_expression (exp=0x6030000d6840, expect_type=0x6210001949f0) at /home/simark/src/binutils-gdb/gdb/eval.c:115
>     #42 0x000055d0b337b0fd in stap_probe::evaluate_argument (this=0x60f0000053b0, n=1, frame=0x6210001ff5e0) at /home/simark/src/binutils-gdb/gdb/stap-probe.c:1435
>     #43 0x000055d0b32d86e8 in svr4_handle_solib_event () at /home/simark/src/binutils-gdb/gdb/solib-svr4.c:1932
>     #44 0x000055d0b32f1f39 in handle_solib_event () at /home/simark/src/binutils-gdb/gdb/solib.c:1258
>     #45 0x000055d0b21e6c62 in bpstat_stop_status (aspace=0x6030000554e0, bp_addr=0x7ffff7fd18d8, thread=0x61700003db80, ws=0x7ffcff02c708, stop_chain=0x0) at /home/simark/src/binutils-gdb/gdb/breakpoint.c:5470
>     #46 0x000055d0b2aa44c2 in handle_signal_stop (ecs=0x7ffcff02c6e0) at /home/simark/src/binutils-gdb/gdb/infrun.c:6254
>     #47 0x000055d0b2aa0962 in handle_inferior_event (ecs=0x7ffcff02c6e0) at /home/simark/src/binutils-gdb/gdb/infrun.c:5740
>     #48 0x000055d0b2a94a0f in fetch_inferior_event () at /home/simark/src/binutils-gdb/gdb/infrun.c:4111
> 
> When the get_frame_id call is done at frame 31, on frame #0, the
> id is not computed yet, and therefore compute_frame_id is called.
> compute_frame_id looks for an unwinder, which goes through the Python
> unwinders.  When value_fetch_lazy_register is called at frame 12,
> get_frame_id is called again for frame #0.  But we are in the process of
> computing that frame id, so it can't work.  The assert in get_frame_id
> works as intended.
> 
> The second call to get_frame_id happens in
> 
>     VALUE_FRAME_ID (val)
> 
> at value.c:3955.  If we dig down this, we see that:
> 
>  1. VALUE_NEXT_FRAME_ID is called first, returning the next frame's id,
>     stored in struct value (it happens to be the sentinel's frame id, in
>     this case)
>  2. it is passed to get_prev_frame_id_by_id
>  3. frame_find_by_id is called on that, that returns the frame_info for
>     the sentinel frame
>  4. get_prev_frame is called on that, that returns a frame_info for our
>     frame #0
>  5. get_frame_id is called on that, this is where the gdb_assert fails.
>  6. had the previous step worked, value_fetch_lazy_register would have
>     called frame_find_by_id on it, to get the frame_info for frame #0
> 
> In the end, all value_fetch_lazy_register wants is a frame_info for the
> value's frame.  In step 4, we have that.  In step 5, we fetch the
> frame's id only to go back to a frame_info in step 6.  That seems
> unnecessary, and causes the internal error.
> 
> Change value_fetch_lazy_register to do the more straightforward thing:
> 
>  - fetch the value's next frame id
>  - fetch the frame info from that
>  - fetch the prev frame from that (the value's frame)
> 
> With this change, the command shown above no longer asserts and the
> produced message makes sense:
> 
>     { value_fetch_lazy (frame=0,regnum=1(rbx),...) -> register=1 bytes=[c0e0fff7ff7f0000] }
> 
> gdb/ChangeLog:
> 
> 	* value.c (value_fetch_lazy_register): Don't use VALUE_FRAME_ID
> 	to fetch value's frame for debug message.

This is a duplicate of the patch I posted here:

  https://sourceware.org/pipermail/gdb-patches/2021-May/179361.html

And then reposted here:

  https://sourceware.org/pipermail/gdb-patches/2021-June/180210.html

In that patch I make the case that VALUE_FRAME_ID is a bad idea (due
to it potentially triggering the above bug) and should be removed.

I also include a test case.

The only difference I see between our fixes is you went with
get_prev_frame, and I went with get_prev_frame_always.  I figured that
if a value had a particular frame-id encoded within it then we really
do want the previous frame, even if, for example, that frame is before
main.

Thanks,
Andrew




> 
> Change-Id: I294f06f8b32206d442da5355f1b897159414e5b6
> ---
>  gdb/value.c | 21 +++++++++------------
>  1 file changed, 9 insertions(+), 12 deletions(-)
> 
> diff --git a/gdb/value.c b/gdb/value.c
> index 9df035a50b3b..6c969a911376 100644
> --- a/gdb/value.c
> +++ b/gdb/value.c
> @@ -3883,8 +3883,6 @@ value_fetch_lazy_memory (struct value *val)
>  static void
>  value_fetch_lazy_register (struct value *val)
>  {
> -  struct frame_info *next_frame;
> -  int regnum;
>    struct type *type = check_typedef (value_type (val));
>    struct value *new_val = val, *mark = value_mark ();
>  
> @@ -3896,8 +3894,8 @@ value_fetch_lazy_register (struct value *val)
>      {
>        struct frame_id next_frame_id = VALUE_NEXT_FRAME_ID (new_val);
>  
> -      next_frame = frame_find_by_id (next_frame_id);
> -      regnum = VALUE_REGNUM (new_val);
> +      frame_info *next_frame = frame_find_by_id (next_frame_id);
> +      int regnum = VALUE_REGNUM (new_val);
>  
>        gdb_assert (next_frame != NULL);
>  
> @@ -3948,18 +3946,17 @@ value_fetch_lazy_register (struct value *val)
>  
>    if (frame_debug)
>      {
> -      struct gdbarch *gdbarch;
> -      struct frame_info *frame;
> -      /* VALUE_FRAME_ID is used here, instead of VALUE_NEXT_FRAME_ID,
> -	 so that the frame level will be shown correctly.  */
> -      frame = frame_find_by_id (VALUE_FRAME_ID (val));
> -      regnum = VALUE_REGNUM (val);
> -      gdbarch = get_frame_arch (frame);
> +      frame_id next_frame_id = VALUE_NEXT_FRAME_ID (val);
> +      frame_info *next_frame = frame_find_by_id (next_frame_id);
> +      frame_info *value_frame = get_prev_frame (next_frame);
> +
> +      int regnum = VALUE_REGNUM (val);
> +      gdbarch *gdbarch = get_frame_arch (value_frame);
>  
>        fprintf_unfiltered (gdb_stdlog,
>  			  "{ value_fetch_lazy "
>  			  "(frame=%d,regnum=%d(%s),...) ",
> -			  frame_relative_level (frame), regnum,
> +			  frame_relative_level (value_frame), regnum,
>  			  user_reg_map_regnum_to_name (gdbarch, regnum));
>  
>        fprintf_unfiltered (gdb_stdlog, "->");
> -- 
> 2.32.0
> 

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

* Re: [PATCH 0/5] Frame debug output improvements
  2021-06-28 17:44 [PATCH 0/5] Frame debug output improvements Simon Marchi
                   ` (5 preceding siblings ...)
  2021-06-28 19:06 ` [PATCH 0/5] Frame debug output improvements Tom Tromey
@ 2021-06-29  9:31 ` Andrew Burgess
  2021-06-29 16:04   ` Simon Marchi
  6 siblings, 1 reply; 11+ messages in thread
From: Andrew Burgess @ 2021-06-29  9:31 UTC (permalink / raw)
  To: Simon Marchi; +Cc: gdb-patches

* Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> [2021-06-28 13:44:24 -0400]:

> I started improving the frame debug messages a while ago, while helping
> Eli figure out why GDB couldn't unwind past a JIT frame.  I've been
> sitting on these changes since, and finally cleaned them up for
> submission.
> 
> While doing so, I found a little bug (that only happens when "set debug
> frame" is in effect), which is fixed by patch 2.
> 
> Simon Marchi (5):
>   gdb: make frame_debug a boolean
>   gdb: value_fetch_lazy_register: fix getting frame id while it is
>     computed
>   gdb: introduce frame_debug_printf
>   gdb: add names to unwinders, add debug messages when looking for
>     unwinder
>   gdb: introduce FRAME_SCOPED_DEBUG_ENTER_EXIT

Patches 1, 3, 4, & 5 LGTM.  This will be a huge improvement for
debugging frame related issues.

See my other email for patch 2.

Thanks,
Andrew


> 
>  gdb/aarch64-tdep.c                            |   2 +
>  gdb/alpha-mdebug-tdep.c                       |   4 +-
>  gdb/alpha-tdep.c                              |   8 +-
>  gdb/amd64-obsd-tdep.c                         |   4 +-
>  gdb/amd64-tdep.c                              |   3 +
>  gdb/amd64-windows-tdep.c                      |  76 ++--
>  gdb/arc-tdep.c                                |   2 +
>  gdb/arm-tdep.c                                |   5 +
>  gdb/avr-tdep.c                                |   1 +
>  gdb/bfin-tdep.c                               |   1 +
>  gdb/bpf-tdep.c                                |   1 +
>  gdb/cris-tdep.c                               |   2 +
>  gdb/csky-tdep.c                               |   2 +
>  gdb/dummy-frame.c                             |   1 +
>  gdb/dwarf2/frame-tailcall.c                   |   1 +
>  gdb/dwarf2/frame.c                            |   2 +
>  gdb/frame-unwind.c                            |  12 +-
>  gdb/frame-unwind.h                            |   1 +
>  gdb/frame.c                                   | 335 +++++++-----------
>  gdb/frame.h                                   |  13 +-
>  gdb/frv-linux-tdep.c                          |   1 +
>  gdb/frv-tdep.c                                |   1 +
>  gdb/ft32-tdep.c                               |   1 +
>  gdb/h8300-tdep.c                              |   1 +
>  gdb/hppa-linux-tdep.c                         |   1 +
>  gdb/hppa-tdep.c                               |   3 +
>  gdb/i386-obsd-tdep.c                          |   1 +
>  gdb/i386-tdep.c                               |   4 +
>  gdb/ia64-tdep.c                               |   4 +
>  gdb/inline-frame.c                            |   1 +
>  gdb/iq2000-tdep.c                             |   1 +
>  gdb/jit.c                                     |   1 +
>  gdb/lm32-tdep.c                               |   1 +
>  gdb/m32c-tdep.c                               |   1 +
>  gdb/m32r-linux-tdep.c                         |   1 +
>  gdb/m32r-tdep.c                               |   1 +
>  gdb/m68hc11-tdep.c                            |   1 +
>  gdb/m68k-linux-tdep.c                         |   1 +
>  gdb/m68k-tdep.c                               |   1 +
>  gdb/mep-tdep.c                                |   1 +
>  gdb/microblaze-tdep.c                         |   1 +
>  gdb/mips-sde-tdep.c                           |   1 +
>  gdb/mips-tdep.c                               |   4 +
>  gdb/mn10300-tdep.c                            |   1 +
>  gdb/moxie-tdep.c                              |   1 +
>  gdb/msp430-tdep.c                             |   1 +
>  gdb/nds32-tdep.c                              |   2 +
>  gdb/nios2-tdep.c                              |   2 +
>  gdb/or1k-tdep.c                               |   1 +
>  gdb/ppc-fbsd-tdep.c                           |   1 +
>  gdb/ppc-obsd-tdep.c                           |   1 +
>  gdb/python/py-unwind.c                        |   1 +
>  gdb/record-btrace.c                           |   2 +
>  gdb/riscv-tdep.c                              |   1 +
>  gdb/rl78-tdep.c                               |   1 +
>  gdb/rs6000-aix-tdep.c                         |   1 +
>  gdb/rs6000-tdep.c                             |   2 +
>  gdb/rx-tdep.c                                 |   2 +
>  gdb/s12z-tdep.c                               |   1 +
>  gdb/s390-linux-tdep.c                         |   1 +
>  gdb/s390-tdep.c                               |   2 +
>  gdb/score-tdep.c                              |   1 +
>  gdb/sentinel-frame.c                          |   1 +
>  gdb/sh-tdep.c                                 |   2 +
>  gdb/sparc-netbsd-tdep.c                       |   1 +
>  gdb/sparc-obsd-tdep.c                         |   1 +
>  gdb/sparc-sol2-tdep.c                         |   1 +
>  gdb/sparc-tdep.c                              |   1 +
>  gdb/sparc64-fbsd-tdep.c                       |   1 +
>  gdb/sparc64-netbsd-tdep.c                     |   1 +
>  gdb/sparc64-obsd-tdep.c                       |   2 +
>  gdb/sparc64-sol2-tdep.c                       |   1 +
>  gdb/sparc64-tdep.c                            |   1 +
>  .../gdb.dwarf2/dw2-reg-undefined.exp          |   5 +-
>  gdb/tic6x-tdep.c                              |   2 +
>  gdb/tilegx-tdep.c                             |   1 +
>  gdb/v850-tdep.c                               |   1 +
>  gdb/value.c                                   |  51 ++-
>  gdb/vax-tdep.c                                |   1 +
>  gdb/xstormy16-tdep.c                          |   1 +
>  gdb/xtensa-tdep.c                             |   1 +
>  81 files changed, 327 insertions(+), 284 deletions(-)
> 
> -- 
> 2.32.0
> 

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

* Re: [PATCH 2/5] gdb: value_fetch_lazy_register: fix getting frame id while it is computed
  2021-06-29  9:27   ` Andrew Burgess
@ 2021-06-29 14:53     ` Simon Marchi
  0 siblings, 0 replies; 11+ messages in thread
From: Simon Marchi @ 2021-06-29 14:53 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gdb-patches

On 2021-06-29 5:27 a.m., Andrew Burgess wrote:
> This is a duplicate of the patch I posted here:
> 
>   https://sourceware.org/pipermail/gdb-patches/2021-May/179361.html
> 
> And then reposted here:
> 
>   https://sourceware.org/pipermail/gdb-patches/2021-June/180210.html

Oh, sorry about that, I missed that (or thought it was already reviewed
by somebody else)!

> In that patch I make the case that VALUE_FRAME_ID is a bad idea (due
> to it potentially triggering the above bug) and should be removed.
> 
> I also include a test case.
> 
> The only difference I see between our fixes is you went with
> get_prev_frame, and I went with get_prev_frame_always.  I figured that
> if a value had a particular frame-id encoded within it then we really
> do want the previous frame, even if, for example, that frame is before
> main.

That all sounds better than my version, so I'll go review it right away.

Simon

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

* Re: [PATCH 0/5] Frame debug output improvements
  2021-06-29  9:31 ` Andrew Burgess
@ 2021-06-29 16:04   ` Simon Marchi
  0 siblings, 0 replies; 11+ messages in thread
From: Simon Marchi @ 2021-06-29 16:04 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gdb-patches



On 2021-06-29 5:31 a.m., Andrew Burgess wrote:
> * Simon Marchi via Gdb-patches <gdb-patches@sourceware.org> [2021-06-28 13:44:24 -0400]:
> 
>> I started improving the frame debug messages a while ago, while helping
>> Eli figure out why GDB couldn't unwind past a JIT frame.  I've been
>> sitting on these changes since, and finally cleaned them up for
>> submission.
>>
>> While doing so, I found a little bug (that only happens when "set debug
>> frame" is in effect), which is fixed by patch 2.
>>
>> Simon Marchi (5):
>>   gdb: make frame_debug a boolean
>>   gdb: value_fetch_lazy_register: fix getting frame id while it is
>>     computed
>>   gdb: introduce frame_debug_printf
>>   gdb: add names to unwinders, add debug messages when looking for
>>     unwinder
>>   gdb: introduce FRAME_SCOPED_DEBUG_ENTER_EXIT
> 
> Patches 1, 3, 4, & 5 LGTM.  This will be a huge improvement for
> debugging frame related issues.
> 

Ok, thanks.  I will push all but patch 2.

Simon

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

end of thread, other threads:[~2021-06-29 16:04 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-28 17:44 [PATCH 0/5] Frame debug output improvements Simon Marchi
2021-06-28 17:44 ` [PATCH 1/5] gdb: make frame_debug a boolean Simon Marchi
2021-06-28 17:44 ` [PATCH 2/5] gdb: value_fetch_lazy_register: fix getting frame id while it is computed Simon Marchi
2021-06-29  9:27   ` Andrew Burgess
2021-06-29 14:53     ` Simon Marchi
2021-06-28 17:44 ` [PATCH 3/5] gdb: introduce frame_debug_printf Simon Marchi
2021-06-28 17:44 ` [PATCH 4/5] gdb: add names to unwinders, add debug messages when looking for unwinder Simon Marchi
2021-06-28 17:44 ` [PATCH 5/5] gdb: introduce FRAME_SCOPED_DEBUG_ENTER_EXIT Simon Marchi
2021-06-28 19:06 ` [PATCH 0/5] Frame debug output improvements Tom Tromey
2021-06-29  9:31 ` Andrew Burgess
2021-06-29 16:04   ` Simon Marchi

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).