Re: PR7580 - Command to force abort when internal error

Pedro Alves
2009-01-25T23:19:10Z

[-- Attachment #1: Type: text/plain, Size: 1282 bytes --]

Hi guys,

Sorry, it seems I dropped the ball on this. I'm not sure if we
reached a consensus or not, but I've tried to address your
comments in this new version. I've dropped the "an" article
from GDB's help strings, as Eli suggested.

On Friday 09 January 2009 14:25:29, Eli Zaretskii wrote:
> There's no need for listing all the possible ACTIONs here. It is
> enough to say
>
> @kindex maint set internal-error
> @kindex maint show internal-error
> @item maint set internal-error @var{action} [ask|yes|no]
> @itemx maint show internal-error @var{action}
>
> and then list all the possible values of @var{action} and explain
> them. As a nice side-effect, this will always make the index less
> cluttered.
>
> I would also add here another index entry, for those who don't
> remember or don't know the command's name, but are still looking for
> this information. How about
>
> @cindex @value{GDBN} internal error
> @cindex internal errors, control of @value{GDBN} behavior
>
> ?

Thanks, I tried to address this one too. There's also
internal-warning in the mix, but we do get less clutter. I didn't
think we'd want a @var internal-error|warning --- too many indirections
are not nice in documentation, IMHO.

What do you think of this version?

--
Pedro Alves

[-- Attachment #2: pr7580.diff --]
[-- Type: text/x-diff, Size: 9569 bytes --]

gdb/
2009-01-25 Pedro Alves <pedro@codesourcery.com>

Add "maint set|show internal-error|internal-warning quit|corefile
ask|yes|no" commands.

PR gdb/7580:
* utils.c (internal_problem_ask, internal_problem_yes)
(internal_problem_no, internal_problem_modes): New.
(struct internal_problem): Remove FIXME. Make should_quit and
should_dump_core types to char *.
(internal_vproblem, internal_error_problem)
(internal_warning_problem): Adjust.
(set_internal_problem_cmd, show_internal_problem_cmd): New dummy
functions.
(add_internal_problem_command): New.
(_initialize_utils): New.

gdb/doc/
2009-01-25 Pedro Alves <pedro@codesourcery.com>

PR gdb/7580:
* gdb.texinfo (Maintenance Commands): Document "maint set|show
internal-error|internal-warning quit|corefile ask|yes|no".

---
gdb/doc/gdb.texinfo | 27 ++++++++
gdb/utils.c | 166 ++++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 162 insertions(+), 31 deletions(-)

Index: src/gdb/utils.c
===================================================================
--- src.orig/gdb/utils.c 2009-01-14 13:37:58.000000000 +0000
+++ src/gdb/utils.c 2009-01-25 22:43:28.000000000 +0000
@@ -825,6 +825,21 @@ error_stream (struct ui_file *stream)
error (("%s"), message);
}

+/* Allow the user to configure the debugger behavior with respect to
+ what to do when an internal problem is detected. */
+
+const char internal_problem_ask[] = "ask";
+const char internal_problem_yes[] = "yes";
+const char internal_problem_no[] = "no";
+static const char *internal_problem_modes[] =
+{
+ internal_problem_ask,
+ internal_problem_yes,
+ internal_problem_no,
+ NULL
+};
+static const char *internal_problem_mode = internal_problem_ask;
+
/* Print a message reporting an internal error/warning. Ask the user
if they want to continue, dump core, or just exit. Return
something to indicate a quit. */
@@ -832,10 +847,8 @@ error_stream (struct ui_file *stream)
struct internal_problem
{
const char *name;
- /* FIXME: cagney/2002-08-15: There should be ``maint set/show''
- commands available for controlling these variables. */
- enum auto_boolean should_quit;
- enum auto_boolean should_dump_core;
+ const char *should_quit;
+ const char *should_dump_core;
};

/* Report a problem, internal to GDB, to the user. Once the problem
@@ -896,42 +909,33 @@ further debugging may prove unreliable."
make_cleanup (xfree, reason);
}

- switch (problem->should_quit)
+ if (problem->should_quit == internal_problem_ask)
{
- case AUTO_BOOLEAN_AUTO:
/* Default (yes/batch case) is to quit GDB. When in batch mode
- this lessens the likelhood of GDB going into an infinate
- loop. */
+ this lessens the likelihood of GDB going into an infinite
+ loop. */
quit_p = query (_("%s\nQuit this debugging session? "), reason);
- break;
- case AUTO_BOOLEAN_TRUE:
- quit_p = 1;
- break;
- case AUTO_BOOLEAN_FALSE:
- quit_p = 0;
- break;
- default:
- internal_error (__FILE__, __LINE__, _("bad switch"));
}
+ else if (problem->should_quit == internal_problem_yes)
+ quit_p = 1;
+ else if (problem->should_quit == internal_problem_no)
+ quit_p = 0;
+ else
+ internal_error (__FILE__, __LINE__, _("bad switch"));

- switch (problem->should_dump_core)
+ if (problem->should_dump_core == internal_problem_ask)
{
- case AUTO_BOOLEAN_AUTO:
/* Default (yes/batch case) is to dump core. This leaves a GDB
`dropping' so that it is easier to see that something went
wrong in GDB. */
dump_core_p = query (_("%s\nCreate a core file of GDB? "), reason);
- break;
- break;
- case AUTO_BOOLEAN_TRUE:
- dump_core_p = 1;
- break;
- case AUTO_BOOLEAN_FALSE:
- dump_core_p = 0;
- break;
- default:
- internal_error (__FILE__, __LINE__, _("bad switch"));
}
+ else if (problem->should_dump_core == internal_problem_yes)
+ dump_core_p = 1;
+ else if (problem->should_dump_core == internal_problem_no)
+ dump_core_p = 0;
+ else
+ internal_error (__FILE__, __LINE__, _("bad switch"));

if (quit_p)
{
@@ -955,7 +959,7 @@ further debugging may prove unreliable."
}

static struct internal_problem internal_error_problem = {
- "internal-error", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO
+ "internal-error", internal_problem_ask, internal_problem_ask
};

NORETURN void
@@ -975,7 +979,7 @@ internal_error (const char *file, int li
}

static struct internal_problem internal_warning_problem = {
- "internal-warning", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO
+ "internal-warning", internal_problem_ask, internal_problem_ask
};

void
@@ -993,6 +997,99 @@ internal_warning (const char *file, int
va_end (ap);
}

+/* Dummy functions to keep add_prefix_cmd happy. */
+
+static void
+set_internal_problem_cmd (char *args, int from_tty)
+{
+}
+
+static void
+show_internal_problem_cmd (char *args, int from_tty)
+{
+}
+
+/* When GDB reports an internal problem (error or warning) it gives
+ the user the opportunity to quit GDB and/or create a core file of
+ the current debug session. This function registers a few commands
+ that make it possible to specify that GDB should always or never
+ quit or create a core file, without asking. The commands look
+ like:
+
+ maint set PROBLEM-NAME quit ask|yes|no
+ maint show PROBLEM-NAME quit
+ maint set PROBLEM-NAME corefile ask|yes|no
+ maint show PROBLEM-NAME corefile
+
+ Where PROBLEM-NAME is currently "internal-error" or
+ "internal-warning". */
+
+static void
+add_internal_problem_command (struct internal_problem *problem)
+{
+ struct cmd_list_element **set_cmd_list;
+ struct cmd_list_element **show_cmd_list;
+ char *set_doc;
+ char *show_doc;
+
+ set_cmd_list = xmalloc (sizeof (*set_cmd_list));
+ show_cmd_list = xmalloc (sizeof (*set_cmd_list));
+ *set_cmd_list = NULL;
+ *show_cmd_list = NULL;
+
+ set_doc = xstrprintf (_("Configure what GDB does when %s is detected."),
+ problem->name);
+
+ show_doc = xstrprintf (_("Show what GDB does when %s is detected."),
+ problem->name);
+
+ add_prefix_cmd ((char*) problem->name,
+ class_maintenance, set_internal_problem_cmd, set_doc,
+ set_cmd_list,
+ concat ("maintenance set ", problem->name, " ", NULL),
+ 0/*allow-unknown*/, &maintenance_set_cmdlist);
+
+ add_prefix_cmd ((char*) problem->name,
+ class_maintenance, show_internal_problem_cmd, show_doc,
+ show_cmd_list,
+ concat ("maintenance show ", problem->name, " ", NULL),
+ 0/*allow-unknown*/, &maintenance_show_cmdlist);
+
+ set_doc = xstrprintf (_("\
+Set whether GDB should quit when an %s is detected"),
+ problem->name);
+ show_doc = xstrprintf (_("\
+Show whether GDB will quit when an %s is detected"),
+ problem->name);
+ add_setshow_enum_cmd ("quit", class_maintenance,
+ internal_problem_modes,
+ &problem->should_quit,
+ set_doc,
+ show_doc,
+ NULL, /* help_doc */
+ NULL, /* setfunc */
+ NULL, /* showfunc */
+ set_cmd_list,
+ show_cmd_list);
+
+ set_doc = xstrprintf (_("\
+Set whether GDB should create a core file of GDB when %s is detected"),
+ problem->name);
+ show_doc = xstrprintf (_("\
+Show whether GDB will create a core file of GDB when %s is detected"),
+ problem->name);
+ add_setshow_enum_cmd ("corefile", class_maintenance,
+ internal_problem_modes,
+ &problem->should_dump_core,
+ set_doc,
+ show_doc,
+ NULL, /* help_doc */
+ NULL, /* setfunc */
+ NULL, /* showfunc */
+ set_cmd_list,
+ show_cmd_list);
+}
+
/* Print the system error message for errno, and also mention STRING
as the file name for which the error was encountered.
Then return to command level. */
@@ -3443,3 +3540,10 @@ gdb_buildargv (const char *s)
nomem (0);
return argv;
}
+
+void
+_initialize_utils (void)
+{
+ add_internal_problem_command (&internal_error_problem);
+ add_internal_problem_command (&internal_warning_problem);
+}
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo 2009-01-25 21:03:20.000000000 +0000
+++ src/gdb/doc/gdb.texinfo 2009-01-25 23:08:58.000000000 +0000
@@ -24798,6 +24798,33 @@ Create a core file? (y or n) @kbd{n}
(@value{GDBP})
@end smallexample

+@cindex @value{GDBN} internal error
+@cindex internal errors, control of @value{GDBN} behavior
+
+@kindex maint set internal-error
+@kindex maint show internal-error
+@kindex maint set internal-warning
+@kindex maint show internal-warning
+@item maint set internal-error @var{action} [ask|yes|no]
+@itemx maint show internal-error @var{action}
+@itemx maint set internal-warning @var{action} [ask|yes|no]
+@itemx maint show internal-warning @var{action}
+When @value{GDBN} reports an internal problem (error or warning) it
+gives the user the opportunity to both quit @value{GDBN} and create a
+core file of the current @value{GDBN} session. These commands let you
+override the default behaviour for each particular @var{action},
+described in the table below.
+
+@table @samp
+@item quit
+You can specify that @value{GDBN} should always (yes) or never (no)
+quit. The default is to ask the user what to do.
+
+@item corefile
+You can specify that @value{GDBN} should always (yes) or never (no)
+create a core file. The default is to ask the user what to do.
+@end table
+
@kindex maint packet
@item maint packet @var{text}
If @value{GDBN} is talking to an inferior via the serial protocol,