2002-08-15 Andrew Cagney * maint.c (maintenance_internal_error): Print the parameter as the error message. (maintenance_internal_warning): New function. (_initialize_maint_cmds): Add command `maint internal-warning'. * defs.h (internal_warning, internal_vwarning): Declare. * utils.c (struct internal_problem): Define. (internal_problem): New function. (internal_warning): New function. (internal_vwarning): New function. (internal_warning_problem, internal_error_problem): New variables. (internal_verror): Just call internal_problem. Index: doc/ChangeLog 2002-08-15 Andrew Cagney * gdb.texinfo (Maintenance Commands): Document ``maint internal-error'' and ``maint internal-warning''. Index: testsuite/ChangeLog 2002-08-15 Andrew Cagney * gdb.base/maint.exp: Check `help maint internal-warning'. Index: defs.h =================================================================== RCS file: /cvs/src/src/gdb/defs.h,v retrieving revision 1.94 diff -u -r1.94 defs.h --- defs.h 1 Aug 2002 17:18:32 -0000 1.94 +++ defs.h 15 Aug 2002 21:21:22 -0000 @@ -889,6 +889,12 @@ extern NORETURN void internal_error (const char *file, int line, const char *, ...) ATTR_NORETURN ATTR_FORMAT (printf, 3, 4); +extern void internal_vwarning (const char *file, int line, + const char *, va_list ap); + +extern void internal_warning (const char *file, int line, + const char *, ...) ATTR_FORMAT (printf, 3, 4); + extern NORETURN void nomem (long) ATTR_NORETURN; /* Reasons for calling throw_exception(). NOTE: all reason values Index: maint.c =================================================================== RCS file: /cvs/src/src/gdb/maint.c,v retrieving revision 1.27 diff -u -r1.27 maint.c --- maint.c 15 Jun 2002 21:07:57 -0000 1.27 +++ maint.c 15 Aug 2002 21:21:22 -0000 @@ -118,8 +118,18 @@ static void maintenance_internal_error (char *args, int from_tty) { - internal_error (__FILE__, __LINE__, - "internal maintenance"); + internal_error (__FILE__, __LINE__, "%s", (args == NULL ? "" : args)); +} + +/* Stimulate the internal error mechanism that GDB uses when an + internal problem is detected. Allows testing of the mechanism. + Also useful when the user wants to drop a core file but not exit + GDB. */ + +static void +maintenance_internal_warning (char *args, int from_tty) +{ + internal_warning (__FILE__, __LINE__, "%s", (args == NULL ? "" : args)); } /* Someday we should allow demangling for things other than just @@ -695,6 +705,11 @@ add_cmd ("internal-error", class_maintenance, maintenance_internal_error, "Give GDB an internal error.\n\ Cause GDB to behave as if an internal error was detected.", + &maintenancelist); + + add_cmd ("internal-warning", class_maintenance, maintenance_internal_warning, + "Give GDB an internal warning.\n\ +Cause GDB to behave as if an internal warning was reported.", &maintenancelist); add_cmd ("demangle", class_maintenance, maintenance_demangle, Index: utils.c =================================================================== RCS file: /cvs/src/src/gdb/utils.c,v retrieving revision 1.76 diff -u -r1.76 utils.c --- utils.c 1 Aug 2002 17:18:33 -0000 1.76 +++ utils.c 15 Aug 2002 21:21:22 -0000 @@ -674,15 +674,26 @@ gdb_lasterr = mem_fileopen (); } -/* Print a message reporting an internal error. Ask the user if they - want to continue, dump core, or just exit. */ +/* 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. */ -NORETURN void -internal_verror (const char *file, int line, - const char *fmt, va_list ap) +struct internal_problem { - static char msg[] = "Internal GDB error: recursive internal error.\n"; - static int dejavu = 0; + 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; +}; + +static void +internal_problem (struct internal_problem *problem, + const char *file, int line, + const char *fmt, va_list ap) +{ + static char msg[] = "Recursive internal problem.\n"; + static int dejavu; int quit_p; int dump_core_p; @@ -704,21 +715,49 @@ /* Try to get the message out */ target_terminal_ours (); - fprintf_unfiltered (gdb_stderr, "%s:%d: gdb-internal-error: ", file, line); + fprintf_unfiltered (gdb_stderr, "%s:%d: %s: ", file, line, problem->name); vfprintf_unfiltered (gdb_stderr, fmt, ap); fputs_unfiltered ("\n", gdb_stderr); - /* Default (yes/batch case) is to quit GDB. When in batch mode this - lessens the likelhood of GDB going into an infinate loop. */ - quit_p = query ("\ -An internal GDB error was detected. This may make further\n\ + switch (problem->should_quit) + { + 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. */ + quit_p = query ("\ +A problem internal to GDB was detected. This may make further\n\ debugging unreliable. Quit this debugging session? "); + break; + case AUTO_BOOLEAN_TRUE: + quit_p = 1; + break; + case AUTO_BOOLEAN_FALSE: + quit_p = 0; + break; + default: + internal_error (__FILE__, __LINE__, "bad switch"); + } - /* Default (yes/batch case) is to dump core. This leaves a GDB - dropping so that it is easier to see that something went wrong to - GDB. */ - dump_core_p = query ("\ + switch (problem->should_dump_core) + { + 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 ("\ Create a core file containing the current state of GDB? "); + 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"); + } if (quit_p) { @@ -737,6 +776,17 @@ } dejavu = 0; +} + +static struct internal_problem internal_error_problem = { + "internal-error", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO +}; + +NORETURN void +internal_verror (const char *file, int line, + const char *fmt, va_list ap) +{ + internal_problem (&internal_error_problem, file, line, fmt, ap); throw_exception (RETURN_ERROR); } @@ -745,8 +795,27 @@ { va_list ap; va_start (ap, string); - internal_verror (file, line, string, ap); + va_end (ap); +} + +static struct internal_problem internal_warning_problem = { + "internal-error", AUTO_BOOLEAN_AUTO, AUTO_BOOLEAN_AUTO +}; + +void +internal_vwarning (const char *file, int line, + const char *fmt, va_list ap) +{ + internal_problem (&internal_warning_problem, file, line, fmt, ap); +} + +void +internal_warning (const char *file, int line, const char *string, ...) +{ + va_list ap; + va_start (ap, string); + internal_vwarning (file, line, string, ap); va_end (ap); } Index: doc/gdb.texinfo =================================================================== RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v retrieving revision 1.111 diff -u -r1.111 gdb.texinfo --- doc/gdb.texinfo 13 Aug 2002 21:39:00 -0000 1.111 +++ doc/gdb.texinfo 15 Aug 2002 21:21:24 -0000 @@ -14195,6 +14195,17 @@ @end table +@kindex maint internal-error +@kindex maint internal-warning +@item maint internal-error +@itemx maint internal-warning +Cause @value{GDBN} to call the internal function @code{internal_error} +or @code{internal_warning} and hence behave as though an internal error +or warning is being reported. + +Takes an optional parameter that is used as the text of the error or +warning message. + @kindex maint print registers @kindex maint print raw-registers @kindex maint print cooked-registers Index: testsuite/gdb.base/maint.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.base/maint.exp,v retrieving revision 1.13 diff -u -r1.13 maint.exp --- testsuite/gdb.base/maint.exp 14 May 2002 18:30:53 -0000 1.13 +++ testsuite/gdb.base/maint.exp 15 Aug 2002 21:21:26 -0000 @@ -513,6 +513,14 @@ timeout { fail "(timeout) help maint internal-error" } } +send_gdb "help maint internal-warning\n" +gdb_expect { + -re "Give GDB an internal warning\\.\r\nCause GDB to behave as if an internal warning was reported\\..*$gdb_prompt $"\ + { pass "help maint internal-warning" } + -re ".*$gdb_prompt $" { fail "help maint internal-warning" } + timeout { fail "(timeout) help maint internal-warning" } + } + send_gdb "help maint print statistics\n" gdb_expect { -re "Print statistics about internal gdb state\\..*$gdb_prompt $"\