aboutsummaryrefslogtreecommitdiff
path: root/gdb/exceptions.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/exceptions.c')
-rw-r--r--gdb/exceptions.c80
1 files changed, 63 insertions, 17 deletions
diff --git a/gdb/exceptions.c b/gdb/exceptions.c
index dab5d9b..781864b 100644
--- a/gdb/exceptions.c
+++ b/gdb/exceptions.c
@@ -69,8 +69,13 @@ struct catcher
enum catcher_state state;
/* Jump buffer pointing back at the exception handler. */
SIGJMP_BUF buf;
- /* Status buffer belonging to that exception handler. */
+ /* Status buffer belonging to the exception handler. */
volatile struct exception *exception;
+ /* Should the error / quit message be printed? Old code assumes
+ that this file prints the error/quit message when first reported.
+ New code instead directly handles the printing of error/quit
+ messages. */
+ int print_message;
/* Saved/current state. */
int mask;
char *saved_error_pre_print;
@@ -88,7 +93,8 @@ static SIGJMP_BUF *
catcher_init (struct ui_out *func_uiout,
char *errstring,
volatile struct exception *exception,
- return_mask mask)
+ return_mask mask,
+ int print_message)
{
struct catcher *new_catcher = XZALLOC (struct catcher);
@@ -99,6 +105,7 @@ catcher_init (struct ui_out *func_uiout,
new_catcher->exception = exception;
new_catcher->mask = mask;
+ new_catcher->print_message = print_message;
/* Override error/quit messages during FUNC. */
new_catcher->saved_error_pre_print = error_pre_print;
@@ -295,6 +302,40 @@ do_write (void *data, const char *buffer, long length_buffer)
}
+void
+exception_print (struct ui_file *file, const char *pre_print,
+ struct exception e)
+{
+ if (e.reason < 0 && e.message != NULL)
+ {
+ target_terminal_ours ();
+ wrap_here (""); /* Force out any buffered output */
+ gdb_flush (file);
+ annotate_error_begin ();
+ if (pre_print)
+ fputs_filtered (pre_print, file);
+
+ /* KLUGE: cagney/2005-01-13: Write the string out one line at a
+ time as that way the MI's behavior is preserved. */
+ {
+ const char *start;
+ const char *end;
+ for (start = e.message; start != NULL; start = end)
+ {
+ end = strchr (start, '\n');
+ if (end == NULL)
+ fputs_filtered (start, file);
+ else
+ {
+ end++;
+ ui_file_write (file, start, end - start);
+ }
+ }
+ }
+ fprintf_filtered (file, "\n");
+ }
+}
+
NORETURN static void
print_and_throw (enum return_reason reason, enum errors error,
const char *prefix, const char *fmt,
@@ -322,18 +363,23 @@ print_and_throw (enum return_reason reason, enum errors error,
xfree (last_message);
last_message = ui_file_xstrdup (tmp_stream, &len);
- if (deprecated_error_begin_hook)
- deprecated_error_begin_hook ();
-
- /* Write the message plus any pre_print to gdb_stderr. */
- target_terminal_ours ();
- wrap_here (""); /* Force out any buffered output */
- gdb_flush (gdb_stdout);
- annotate_error_begin ();
- if (error_pre_print)
- fputs_filtered (error_pre_print, gdb_stderr);
- ui_file_put (tmp_stream, do_write, gdb_stderr);
- fprintf_filtered (gdb_stderr, "\n");
+ /* Print the mesage to stderr, but only if the catcher isn't going
+ to handle/print it locally. */
+ if (current_catcher->print_message)
+ {
+ if (deprecated_error_begin_hook)
+ deprecated_error_begin_hook ();
+
+ /* Write the message plus any pre_print to gdb_stderr. */
+ target_terminal_ours ();
+ wrap_here (""); /* Force out any buffered output */
+ gdb_flush (gdb_stdout);
+ annotate_error_begin ();
+ if (error_pre_print)
+ fputs_filtered (error_pre_print, gdb_stderr);
+ ui_file_put (tmp_stream, do_write, gdb_stderr);
+ fprintf_filtered (gdb_stderr, "\n");
+ }
/* Throw the exception. */
e.reason = reason;
@@ -417,7 +463,7 @@ catch_exception (struct ui_out *uiout,
{
volatile struct exception exception;
SIGJMP_BUF *catch;
- catch = catcher_init (uiout, NULL, &exception, mask);
+ catch = catcher_init (uiout, NULL, &exception, mask, 0);
for (SIGSETJMP ((*catch));
catcher_state_machine (CATCH_ITER);)
(*func) (uiout, func_args);
@@ -434,7 +480,7 @@ catch_exceptions_with_msg (struct ui_out *uiout,
{
volatile struct exception exception;
volatile int val = 0;
- SIGJMP_BUF *catch = catcher_init (uiout, errstring, &exception, mask);
+ SIGJMP_BUF *catch = catcher_init (uiout, errstring, &exception, mask, 1);
for (SIGSETJMP ((*catch)); catcher_state_machine (CATCH_ITER);)
val = (*func) (uiout, func_args);
gdb_assert (val >= 0);
@@ -462,7 +508,7 @@ catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
{
volatile int val = 0;
volatile struct exception exception;
- SIGJMP_BUF *catch = catcher_init (uiout, errstring, &exception, mask);
+ SIGJMP_BUF *catch = catcher_init (uiout, errstring, &exception, mask, 1);
/* This illustrates how it is possible to nest the mechanism and
hence catch "break". Of course this doesn't address the need to
also catch "return". */