From 1cf1b22ba22ffaadf3240c53f77392b4801ac706 Mon Sep 17 00:00:00 2001 From: cagney Date: Wed, 18 Sep 2002 23:53:49 +0000 Subject: [PATCH] 2002-09-18 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_vproblem): New function. (internal_warning): New function. (internal_vwarning): New function. (internal_warning_problem, internal_error_problem): New variables. (internal_verror): Just call internal_vproblem. Index: testsuite/ChangeLog 2002-09-18 Andrew Cagney * gdb.base/maint.exp: Check `help maint internal-warning'. --- gdb/ChangeLog | 15 +++++ gdb/defs.h | 6 ++ gdb/maint.c | 19 +++++- gdb/testsuite/ChangeLog | 4 ++ gdb/testsuite/gdb.base/maint.exp | 8 +++ gdb/utils.c | 122 ++++++++++++++++++++++++++++++++------- 6 files changed, 151 insertions(+), 23 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 406e9a5f04..a130ee2477 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,18 @@ +2002-09-18 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_vproblem): New function. + (internal_warning): New function. + (internal_vwarning): New function. + (internal_warning_problem, internal_error_problem): New variables. + (internal_verror): Just call internal_vproblem. + 2002-09-18 Michael Snyder * objc-lang.c: New file, support for Objective-C. diff --git a/gdb/defs.h b/gdb/defs.h index 89a90d6fba..235d285238 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -889,6 +889,12 @@ extern NORETURN void internal_verror (const char *file, int line, 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 diff --git a/gdb/maint.c b/gdb/maint.c index f09703f772..6a849f9c87 100644 --- a/gdb/maint.c +++ b/gdb/maint.c @@ -118,8 +118,18 @@ maintenance_dump_me (char *args, int from_tty) 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 @@ -697,6 +707,11 @@ itself a SIGQUIT signal.", 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, "Demangle a C++ mangled name.\n\ Call internal GDB demangler routine to demangle a C++ link name\n\ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 0d8884a318..2dda46de89 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2002-09-18 Andrew Cagney + + * gdb.base/maint.exp: Check `help maint internal-warning'. + 2002-09-18 David Carlton * gdb.c++/m-static.exp: Remove breakpoints depending on line diff --git a/gdb/testsuite/gdb.base/maint.exp b/gdb/testsuite/gdb.base/maint.exp index ac2e9f8752..51f4c9db20 100644 --- a/gdb/testsuite/gdb.base/maint.exp +++ b/gdb/testsuite/gdb.base/maint.exp @@ -513,6 +513,14 @@ gdb_expect { 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 $"\ diff --git a/gdb/utils.c b/gdb/utils.c index 0c46f794e1..92c097a7f8 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -674,19 +674,34 @@ error_init (void) 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; +}; + +/* Report a problem, internal to GDB, to the user. Once the problem + has been reported, and assuming GDB didn't quit, the caller can + either allow execution to resume or throw an error. */ + +static void +internal_vproblem (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; - /* don't allow infinite error recursion. */ + /* Don't allow infinite error/warning recursion. */ switch (dejavu) { case 0: @@ -702,23 +717,58 @@ internal_verror (const char *file, int line, exit (1); } - /* Try to get the message out */ + /* Try to get the message out and at the start of a new line. */ target_terminal_ours (); - fprintf_unfiltered (gdb_stderr, "%s:%d: gdb-internal-error: ", file, line); + begin_line (); + + /* The error/warning message. Format using a style similar to a + compiler error message. */ + 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\ -debugging unreliable. Quit this debugging session? "); + /* Provide more details so that the user knows that they are living + on the edge. */ + fprintf_unfiltered (gdb_stderr, "\ +A problem internal to GDB has been detected. Further\n\ +debugging may prove unreliable.\n"); - /* 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 ("\ -Create a core file containing the current state of GDB? "); + 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 ("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"); + } + + 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 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 +787,17 @@ Create a core file containing the current state of GDB? "); } 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_vproblem (&internal_error_problem, file, line, fmt, ap); throw_exception (RETURN_ERROR); } @@ -745,11 +806,30 @@ internal_error (const char *file, int line, const char *string, ...) { 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_vproblem (&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); +} + /* The strerror() function can return NULL for errno values that are out of range. Provide a "safe" version that always returns a printable string. */ -- 2.11.0