#include "defs.h"
#include "dyn-string.h"
-#include "gdb_assert.h"
#include <ctype.h>
-#include <string.h>
#include "gdb_wait.h"
#include "event-top.h"
-#include "exceptions.h"
#include "gdbthread.h"
#include "fnmatch.h"
#include "gdb_bfd.h"
(void *) (uintptr_t) saved_lang);
}
+/* Helper function for make_cleanup_clear_parser_state. */
+
+static void
+do_clear_parser_state (void *ptr)
+{
+ struct parser_state **p = (struct parser_state **) ptr;
+
+ *p = NULL;
+}
+
+/* Clean (i.e., set to NULL) the parser state variable P. */
+
+struct cleanup *
+make_cleanup_clear_parser_state (struct parser_state **p)
+{
+ return make_cleanup (do_clear_parser_state, (void *) p);
+}
+
/* This function is useful for cleanups.
Do
(*deprecated_warning_hook) (string, args);
else
{
- target_terminal_ours ();
- wrap_here (""); /* Force out any buffered output. */
+ if (target_supports_terminal_ours ())
+ target_terminal_ours ();
+ if (filtered_printing_initialized ())
+ wrap_here (""); /* Force out any buffered output. */
gdb_flush (gdb_stdout);
if (warning_pre_print)
fputs_unfiltered (warning_pre_print, gdb_stderr);
vfprintf_unfiltered (gdb_stderr, string, args);
fprintf_unfiltered (gdb_stderr, "\n");
- va_end (args);
}
}
-/* Print a warning message.
- The first argument STRING is the warning message, used as a fprintf string,
- and the remaining args are passed as arguments to it.
- The primary difference between warnings and errors is that a warning
- does not force the return to command level. */
-
-void
-warning (const char *string, ...)
-{
- va_list args;
-
- va_start (args, string);
- vwarning (string, args);
- va_end (args);
-}
-
/* Print an error message and return to command level.
The first argument STRING is the error message, used as a fprintf string,
and the remaining args are passed as arguments to it. */
}
void
-error (const char *string, ...)
+error_stream (struct ui_file *stream)
{
- va_list args;
-
- va_start (args, string);
- throw_verror (GENERIC_ERROR, string, args);
- va_end (args);
-}
-
-/* Print an error message and quit.
- The first argument STRING is the error message, used as a fprintf string,
- and the remaining args are passed as arguments to it. */
+ char *message = ui_file_xstrdup (stream, NULL);
-void
-vfatal (const char *string, va_list args)
-{
- throw_vfatal (string, args);
+ make_cleanup (xfree, message);
+ error (("%s"), message);
}
-void
-fatal (const char *string, ...)
-{
- va_list args;
-
- va_start (args, string);
- throw_vfatal (string, args);
- va_end (args);
-}
+/* Emit a message and abort. */
-void
-error_stream (struct ui_file *stream)
+static void ATTRIBUTE_NORETURN
+abort_with_message (const char *msg)
{
- char *message = ui_file_xstrdup (stream, NULL);
+ if (gdb_stderr == NULL)
+ fputs (msg, stderr);
+ else
+ fputs_unfiltered (msg, gdb_stderr);
- make_cleanup (xfree, message);
- error (("%s"), message);
+ abort (); /* NOTE: GDB has only three calls to abort(). */
}
/* Dump core trying to increase the core soft limit to hard limit first. */
-static void
+void
dump_core (void)
{
#ifdef HAVE_SETRLIMIT
}
/* Check whether GDB will be able to dump core using the dump_core
- function. */
+ function. Returns zero if GDB cannot or should not dump core.
+ If LIMIT_KIND is LIMIT_CUR the user's soft limit will be respected.
+ If LIMIT_KIND is LIMIT_MAX only the hard limit will be respected. */
-static int
-can_dump_core (const char *reason)
+int
+can_dump_core (enum resource_limit_kind limit_kind)
{
#ifdef HAVE_GETRLIMIT
struct rlimit rlim;
if (getrlimit (RLIMIT_CORE, &rlim) != 0)
return 1;
- if (rlim.rlim_max == 0)
+ switch (limit_kind)
{
- fprintf_unfiltered (gdb_stderr,
- _("%s\nUnable to dump core, use `ulimit -c"
- " unlimited' before executing GDB next time.\n"),
- reason);
- return 0;
+ case LIMIT_CUR:
+ if (rlim.rlim_cur == 0)
+ return 0;
+
+ case LIMIT_MAX:
+ if (rlim.rlim_max == 0)
+ return 0;
}
#endif /* HAVE_GETRLIMIT */
return 1;
}
+/* Print a warning that we cannot dump core. */
+
+void
+warn_cant_dump_core (const char *reason)
+{
+ fprintf_unfiltered (gdb_stderr,
+ _("%s\nUnable to dump core, use `ulimit -c"
+ " unlimited' before executing GDB next time.\n"),
+ reason);
+}
+
+/* Check whether GDB will be able to dump core using the dump_core
+ function, and print a warning if we cannot. */
+
+static int
+can_dump_core_warn (enum resource_limit_kind limit_kind,
+ const char *reason)
+{
+ int core_dump_allowed = can_dump_core (limit_kind);
+
+ if (!core_dump_allowed)
+ warn_cant_dump_core (reason);
+
+ return core_dump_allowed;
+}
+
/* Allow the user to configure the debugger behavior with respect to
what to do when an internal problem is detected. */
struct internal_problem
{
const char *name;
+ int user_settable_should_quit;
const char *should_quit;
+ int user_settable_should_dump_core;
const char *should_dump_core;
};
break;
case 1:
dejavu = 2;
- fputs_unfiltered (msg, gdb_stderr);
- abort (); /* NOTE: GDB has only three calls to abort(). */
+ abort_with_message (msg);
default:
dejavu = 3;
/* Newer GLIBC versions put the warn_unused_result attribute
}
}
- /* Try to get the message out and at the start of a new line. */
- target_terminal_ours ();
- begin_line ();
-
/* Create a string containing the full error/warning message. Need
to call query with this full string, as otherwize the reason
(error/warning) and question become separated. Format using a
make_cleanup (xfree, reason);
}
+ /* Fall back to abort_with_message if gdb_stderr is not set up. */
+ if (gdb_stderr == NULL)
+ {
+ fputs (reason, stderr);
+ abort_with_message ("\n");
+ }
+
+ /* Try to get the message out and at the start of a new line. */
+ if (target_supports_terminal_ours ())
+ target_terminal_ours ();
+ if (filtered_printing_initialized ())
+ begin_line ();
+
+ /* Emit the message unless query will emit it below. */
+ if (problem->should_quit != internal_problem_ask
+ || !confirm
+ || !filtered_printing_initialized ())
+ fprintf_unfiltered (gdb_stderr, "%s\n", reason);
+
if (problem->should_quit == internal_problem_ask)
{
/* Default (yes/batch case) is to quit GDB. When in batch mode
this lessens the likelihood of GDB going into an infinite
loop. */
- if (!confirm)
- {
- /* Emit the message and quit. */
- fputs_unfiltered (reason, gdb_stderr);
- fputs_unfiltered ("\n", gdb_stderr);
- quit_p = 1;
- }
+ if (!confirm || !filtered_printing_initialized ())
+ quit_p = 1;
else
quit_p = query (_("%s\nQuit this debugging session? "), reason);
}
else
internal_error (__FILE__, __LINE__, _("bad switch"));
+ fputs_unfiltered (_("\nThis is a bug, please report it."), gdb_stderr);
+ if (REPORT_BUGS_TO[0])
+ fprintf_unfiltered (gdb_stderr, _(" For instructions, see:\n%s."),
+ REPORT_BUGS_TO);
+ fputs_unfiltered ("\n\n", gdb_stderr);
+
if (problem->should_dump_core == internal_problem_ask)
{
- if (!can_dump_core (reason))
+ if (!can_dump_core_warn (LIMIT_MAX, reason))
dump_core_p = 0;
+ else if (!filtered_printing_initialized ())
+ dump_core_p = 1;
else
{
/* Default (yes/batch case) is to dump core. This leaves a GDB
}
}
else if (problem->should_dump_core == internal_problem_yes)
- dump_core_p = can_dump_core (reason);
+ dump_core_p = can_dump_core_warn (LIMIT_MAX, reason);
else if (problem->should_dump_core == internal_problem_no)
dump_core_p = 0;
else
}
static struct internal_problem internal_error_problem = {
- "internal-error", internal_problem_ask, internal_problem_ask
+ "internal-error", 1, internal_problem_ask, 1, internal_problem_ask
};
void
internal_verror (const char *file, int line, const char *fmt, va_list ap)
{
internal_vproblem (&internal_error_problem, file, line, fmt, ap);
- fatal (_("Command aborted."));
+ throw_quit (_("Command aborted."));
}
+static struct internal_problem internal_warning_problem = {
+ "internal-warning", 1, internal_problem_ask, 1, internal_problem_ask
+};
+
void
-internal_error (const char *file, int line, const char *string, ...)
+internal_vwarning (const char *file, int line, const char *fmt, va_list ap)
{
- va_list ap;
-
- va_start (ap, string);
- internal_verror (file, line, string, ap);
- va_end (ap);
+ internal_vproblem (&internal_warning_problem, file, line, fmt, ap);
}
-static struct internal_problem internal_warning_problem = {
- "internal-warning", internal_problem_ask, internal_problem_ask
+static struct internal_problem demangler_warning_problem = {
+ "demangler-warning", 1, internal_problem_ask, 0, internal_problem_no
};
void
-internal_vwarning (const char *file, int line, const char *fmt, va_list ap)
+demangler_vwarning (const char *file, int line, const char *fmt, va_list ap)
{
- internal_vproblem (&internal_warning_problem, file, line, fmt, ap);
+ internal_vproblem (&demangler_warning_problem, file, line, fmt, ap);
}
void
-internal_warning (const char *file, int line, const char *string, ...)
+demangler_warning (const char *file, int line, const char *string, ...)
{
va_list ap;
va_start (ap, string);
- internal_vwarning (file, line, string, ap);
+ demangler_vwarning (file, line, string, ap);
va_end (ap);
}
(char *) 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);
-
- xfree (set_doc);
- xfree (show_doc);
-
- 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);
+ if (problem->user_settable_should_quit)
+ {
+ 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);
+
+ xfree (set_doc);
+ xfree (show_doc);
+ }
- xfree (set_doc);
- xfree (show_doc);
+ if (problem->user_settable_should_dump_core)
+ {
+ 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);
+
+ xfree (set_doc);
+ xfree (show_doc);
+ }
}
/* Return a newly allocated string, containing the PREFIX followed
void
quit (void)
{
+ if (sync_quit_force_run)
+ {
+ sync_quit_force_run = 0;
+ quit_force (NULL, stdin == instream);
+ }
+
#ifdef __MSDOS__
/* No steenking SIGINT will ever be coming our way when the
program is resumed. Don't lie. */
- fatal ("Quit");
+ throw_quit ("Quit");
#else
if (job_control
/* If there is no terminal switching for this target, then we can't
possibly get screwed by the lack of job control. */
- || current_target.to_terminal_ours == NULL)
- fatal ("Quit");
+ || !target_supports_terminal_ours ())
+ throw_quit ("Quit");
else
- fatal ("Quit (expect signal SIGINT when the program is resumed)");
+ throw_quit ("Quit (expect signal SIGINT when the program is resumed)");
#endif
}
/* Print the character C on STREAM as part of the contents of a literal
string whose delimiter is QUOTER. Note that this routine should only
be call for printing things which are independent of the language
- of the program being debugged. */
+ of the program being debugged.
+
+ printchar will normally escape backslashes and instances of QUOTER. If
+ QUOTER is 0, printchar won't escape backslashes or any quoting character.
+ As a side effect, if you pass the backslash character as the QUOTER,
+ printchar will escape backslashes as usual, but not any other quoting
+ character. */
static void
printchar (int c, void (*do_fputs) (const char *, struct ui_file *),
}
else
{
- if (c == '\\' || c == quoter)
+ if (quoter != 0 && (c == '\\' || c == quoter))
do_fputs ("\\", stream);
do_fprintf (stream, "%c", c);
}
set_width ();
}
+/* Return nonzero if filtered printing is initialized. */
+int
+filtered_printing_initialized (void)
+{
+ return wrap_buffer != NULL;
+}
+
/* Helper for make_cleanup_restore_page_info. */
static void
immediate_quit++;
QUIT;
+
+ /* We'll need to handle input. */
+ target_terminal_ours ();
+
/* On a real operating system, the user can quit with SIGINT.
But not on GO32.
void *
hashtab_obstack_allocate (void *data, size_t size, size_t count)
{
- unsigned int total = size * count;
+ size_t total = size * count;
void *ptr = obstack_alloc ((struct obstack *) data, total);
memset (ptr, 0, total);
/* Return ARGS parsed as a valid pid, or throw an error. */
int
-parse_pid_to_attach (char *args)
+parse_pid_to_attach (const char *args)
{
unsigned long pid;
char *dummy;
if (!args)
error_no_arg (_("process-id to attach"));
- dummy = args;
+ dummy = (char *) args;
pid = strtoul (args, &dummy, 0);
/* Some targets don't set errno on errors, grrr! */
if ((pid == 0 && dummy == args) || dummy != &args[strlen (args)])
{
add_internal_problem_command (&internal_error_problem);
add_internal_problem_command (&internal_warning_problem);
+ add_internal_problem_command (&demangler_warning_problem);
}