[PATCH] Add support to control auto-display behavior

Christopher Layne clayne@anodized.com
Fri Apr 6 11:04:00 GMT 2007


This patch is to allow setting how auto-displays are affected when memory is
not accessible. It's very common to, when single-stepping, or stepping over,
initially setup some auto-displays and then begin stepping. I don't see
any reason why, in the event an object is not accessible, the auto-display
should be disabled. I know that the actual error is "To prevent infinite
recursion" but I'm not finding how that will happen based on the already
present code. Is it something from the past?  

Basically, it does the following:

(gdb) b main
Breakpoint 1 at 0x8048371: file null.c, line 5.
(gdb) r

Breakpoint 1, main () at null.c:5
5               char buf[][64] = { "foo", "bar" };
(gdb) set display strict off
(gdb) disp q
(gdb) disp *q
(gdb) n
6               char *q = NULL;
2: *q = -115 '\215'
1: q = 0x8048426 "\215\203 ÿÿÿ\215"
(gdb)
8               q = NULL;
2: *q = Cannot access memory at address 0x0
1: q = 0x0
(gdb)
9               q = buf[0];
2: *q = Cannot access memory at address 0x0
1: q = 0x0
(gdb)
10              q = buf[1];
2: *q = 102 'f'
1: q = 0xbfeec3fc "foo"
(gdb)
11              q = (void *)0xDEAD;
2: *q = 98 'b'
1: q = 0xbfeec43c "bar"
(gdb)
13              return 0;
2: *q = Cannot access memory at address 0xdead
1: q = 0xdead <Address 0xdead out of bounds>
(gdb)


Additionally, in the exercising of implementing it, it also fixes a "bug"
where if a display is disabled, as per default behavior, the rest
of the valid displays will still be displayed. Previously things would
just stop at the first exception caught.

(gdb) set display strict on
(gdb) n
8               q = NULL;
Disabling display 2 to avoid infinite recursion.
2: *q = Cannot access memory at address 0x0
1: q = 0x0


gdb/ChangeLog:

2007-03-30  Christopher Layne  <clayne@anodized.com>

	* cli/cli-cmds.c (setdisplaylist): Define.
	(showdisplaylist): Define.
	(init_cmd_lists): Initialize both.
	* cli/cli-cmds.h (setdisplaylist): Declare.
	(showdisplaylist): Declare.
	* gdbcmd.h (setdisplaylist): Declare.
	(showdisplaylist): Declare.
	* printcmd.c (exceptions.h): Include.
	(display_strict): Define and initialize.
	(show_display_strict): New function.
	(show_display): New function.
	(set_display): New function.
	(do_one_display): Change prototype to be compatible with
	catch_errors(). Change return values to fit new prototype.
	(do_displays): Wrap do_one_display in catch_errors().
	(disable_current_display): Check value of display_strict first.
	(_initialize_printcmd): Add prefix commands for controlling
	auto-displays and value of display_strict. Default display_strict to 1.

gdb/doc/ChangeLog:

2007-03-30  Christopher Layne  <clayne@anodized.com>

	* gdb.texinfo (Display Settings): Add documentation for manipulating
	auto-displays.

-cl
-------------- next part --------------
diff -U3 -r gdb-6.6/gdb/cli/cli-cmds.c /usr/local/build/gdb-6.6/gdb/cli/cli-cmds.c
--- gdb-6.6/gdb/cli/cli-cmds.c	2006-10-27 15:23:20.000000000 -0700
+++ /usr/local/build/gdb-6.6/gdb/cli/cli-cmds.c	2007-03-30 00:58:40.000000000 -0700
@@ -178,6 +178,10 @@
 
 struct cmd_list_element *showchecklist;
 
+struct cmd_list_element *setdisplaylist;
+
+struct cmd_list_element *showdisplaylist;
+
 /* Command tracing state.  */
 
 int source_verbose = 0;
@@ -1108,6 +1112,8 @@
   showprintlist = NULL;
   setchecklist = NULL;
   showchecklist = NULL;
+  setdisplaylist = NULL;
+  showdisplaylist = NULL;
 }
 
 static void
diff -U3 -r gdb-6.6/gdb/cli/cli-cmds.h /usr/local/build/gdb-6.6/gdb/cli/cli-cmds.h
--- gdb-6.6/gdb/cli/cli-cmds.h	2006-10-27 15:23:20.000000000 -0700
+++ /usr/local/build/gdb-6.6/gdb/cli/cli-cmds.h	2007-03-30 00:57:39.000000000 -0700
@@ -103,6 +103,10 @@
 
 extern struct cmd_list_element *showchecklist;
 
+extern struct cmd_list_element *setdisplaylist;
+
+extern struct cmd_list_element *showdisplaylist;
+
 /* Exported to gdb/top.c */
 
 void init_cmd_lists (void);
diff -U3 -r gdb-6.6/gdb/doc/gdb.texinfo /usr/local/build/gdb-6.6/gdb/doc/gdb.texinfo
--- gdb-6.6/gdb/doc/gdb.texinfo	2006-11-14 13:53:59.000000000 -0800
+++ /usr/local/build/gdb-6.6/gdb/doc/gdb.texinfo	2007-04-06 03:05:16.000000000 -0700
@@ -5391,6 +5391,7 @@
 * Output Formats::              Output formats
 * Memory::                      Examining memory
 * Auto Display::                Automatic display
+* Display Settings::            Display settings
 * Print Settings::              Print settings
 * Value History::               Value history
 * Convenience Vars::            Convenience variables
@@ -5963,6 +5964,32 @@
 automatically.  The next time your program stops where @code{last_char}
 is meaningful, you can enable the display expression once again.
 
+@node Display Settings
+@section Display settings
+
+@cindex display options
+@cindex display settings
+@value{GDBN} provides the following ways to control how auto-displays are
+handled.
+
+@table @code
+@kindex set display
+@item set display strict
+@itemx set display strict on
+@cindex disable/permit auto-displays on memory access error
+@value{GDBN} automatically disables any auto-display which encounters a
+memory access error during display. The default is @code{on}.
+
+@item set display strict off
+Do not disable any auto-display which encounters a memory access error,
+but instead print a general error message rather than displaying a
+non-accessible value.
+
+@kindex show display
+@item show display strict
+Show whether or not auto-displays are disabled on memory access error.
+@end table
+
 @node Print Settings
 @section Print settings
 
diff -U3 -r gdb-6.6/gdb/gdbcmd.h /usr/local/build/gdb-6.6/gdb/gdbcmd.h
--- gdb-6.6/gdb/gdbcmd.h	2006-10-27 15:23:20.000000000 -0700
+++ /usr/local/build/gdb-6.6/gdb/gdbcmd.h	2007-03-30 00:56:48.000000000 -0700
@@ -122,6 +122,10 @@
 
 extern struct cmd_list_element *showchecklist;
 
+extern struct cmd_list_element *setdisplaylist;
+
+extern struct cmd_list_element *showdisplaylist;
+
 extern void execute_command (char *, int);
 
 enum command_control_type execute_control_command (struct command_line *);
diff -U3 -r gdb-6.6/gdb/printcmd.c /usr/local/build/gdb-6.6/gdb/printcmd.c
--- gdb-6.6/gdb/printcmd.c	2006-10-17 13:17:44.000000000 -0700
+++ /usr/local/build/gdb-6.6/gdb/printcmd.c	2007-03-30 03:24:16.000000000 -0700
@@ -43,6 +43,7 @@
 #include "gdb_assert.h"
 #include "block.h"
 #include "disasm.h"
+#include "exceptions.h"		/* to handle auto-display access errors */
 
 #ifdef TUI
 #include "tui/tui.h"		/* For tui_active et.al.   */
@@ -104,6 +105,32 @@
 		    value);
 }
 
+/* Enable disabling of an auto-display which cannot be displayed
+   due to a memory error. */
+static int display_strict = 0;
+static void
+show_display_strict (struct ui_file *file, int from_tty,
+			    struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("\
+Disabling of display on memory access error is %s.\n"),
+		    value);
+}
+
+static void
+set_display (char *arg, int from_tty)
+{
+  printf_unfiltered (
+     "\"set display\" must be followed by the name of a display subcommand.\n");
+  help_list (setdisplaylist, "set display ", -1, gdb_stdout);
+}
+
+static void
+show_display (char *args, int from_tty)
+{
+  cmd_show_list (showdisplaylist, from_tty, "");
+}
+
 /* Number of auto-display expression currently being displayed.
    So that we can disable it if we get an error or a signal within it.
    -1 when not doing one.  */
@@ -148,7 +175,7 @@
 
 /* Prototypes for local functions. */
 
-static void do_one_display (struct display *);
+static int do_one_display (void *);
 

 
 /* Decode a format specification.  *STRING_PTR should point to it.
@@ -1468,20 +1495,21 @@
    Do nothing if the display cannot be printed in the current context,
    or if the display is disabled. */
 
-static void
-do_one_display (struct display *d)
+static int
+do_one_display (void *p)
 {
+  struct display *d = p;
   int within_current_scope;
 
   if (d->enabled_p == 0)
-    return;
+    return 0;
 
   if (d->block)
     within_current_scope = contained_in (get_selected_block (0), d->block);
   else
     within_current_scope = 1;
   if (!within_current_scope)
-    return;
+    return 0;
 
   current_display_number = d->number;
 
@@ -1548,6 +1576,8 @@
 
   gdb_flush (gdb_stdout);
   current_display_number = -1;
+
+  return 0;
 }
 
 /* Display all of the values on the auto-display chain which can be
@@ -1559,7 +1589,7 @@
   struct display *d;
 
   for (d = display_chain; d; d = d->next)
-    do_one_display (d);
+    catch_errors (do_one_display, d, "", RETURN_MASK_ALL);
 }
 
 /* Delete the auto-display which we were in the process of displaying.
@@ -1582,6 +1612,7 @@
 void
 disable_current_display (void)
 {
+  if (display_strict == 0) return;
   if (current_display_number >= 0)
     {
       disable_display (current_display_number);
@@ -2165,6 +2196,23 @@
 No argument means cancel all automatic-display expressions.\n\
 Do \"info display\" to see current list of code numbers."), &deletelist);
 
+  add_prefix_cmd ("display", no_class, set_display,
+		  _("Generic command for setting how auto-displays work."),
+		  &setdisplaylist, "set display ", 0, &setlist);
+
+  add_prefix_cmd ("display", no_class, show_display,
+		  _("Generic command for showing auto-display settings."),
+		  &showdisplaylist, "show display ", 0, &showlist);
+
+  add_setshow_boolean_cmd ("strict", class_vars, 
+			   &display_strict, _("\
+Set disabling of display on memory access error."), _("\
+Show disabling of display on memory access error."),
+			   NULL,
+			   NULL,
+			   show_display_strict,
+			   &setdisplaylist, &showdisplaylist);
+
   add_com ("printf", class_vars, printf_command, _("\
 printf \"printf format string\", arg1, arg2, arg3, ..., argn\n\
 This is useful for formatted output in user-defined commands."));
@@ -2267,4 +2315,5 @@
   examine_w_type = init_type (TYPE_CODE_INT, 4, 0, "examine_w_type", NULL);
   examine_g_type = init_type (TYPE_CODE_INT, 8, 0, "examine_g_type", NULL);
 
+  display_strict = 1;
 }


More information about the Gdb-patches mailing list