123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- /* Exception (throw catch) mechanism, for GDB, the GNU debugger.
- Copyright (C) 1986-2022 Free Software Foundation, Inc.
- This file is part of GDB.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
- #include "defs.h"
- #include "exceptions.h"
- #include "breakpoint.h"
- #include "target.h"
- #include "inferior.h"
- #include "annotate.h"
- #include "ui-out.h"
- #include "serial.h"
- #include "gdbthread.h"
- #include "top.h"
- #include "gdbsupport/gdb_optional.h"
- static void
- print_flush (void)
- {
- struct ui *ui = current_ui;
- struct serial *gdb_stdout_serial;
- if (deprecated_error_begin_hook)
- deprecated_error_begin_hook ();
- gdb::optional<target_terminal::scoped_restore_terminal_state> term_state;
- if (target_supports_terminal_ours ())
- {
- term_state.emplace ();
- target_terminal::ours_for_output ();
- }
- /* We want all output to appear now, before we print the error. We
- have 2 levels of buffering we have to flush (it's possible that
- some of these should be changed to flush the lower-level ones
- too): */
- /* 1. The stdio buffer. */
- gdb_flush (gdb_stdout);
- gdb_flush (gdb_stderr);
- /* 2. The system-level buffer. */
- gdb_stdout_serial = serial_fdopen (fileno (ui->outstream));
- if (gdb_stdout_serial)
- {
- serial_drain_output (gdb_stdout_serial);
- serial_un_fdopen (gdb_stdout_serial);
- }
- annotate_error_begin ();
- }
- static void
- print_exception (struct ui_file *file, const struct gdb_exception &e)
- {
- /* KLUDGE: 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.what (); start != NULL; start = end)
- {
- end = strchr (start, '\n');
- if (end == NULL)
- gdb_puts (start, file);
- else
- {
- end++;
- file->write (start, end - start);
- }
- }
- gdb_printf (file, "\n");
- /* Now append the annotation. */
- switch (e.reason)
- {
- case RETURN_QUIT:
- annotate_quit ();
- break;
- case RETURN_ERROR:
- /* Assume that these are all errors. */
- annotate_error ();
- break;
- default:
- internal_error (__FILE__, __LINE__, _("Bad switch."));
- }
- }
- void
- exception_print (struct ui_file *file, const struct gdb_exception &e)
- {
- if (e.reason < 0 && e.message != NULL)
- {
- print_flush ();
- print_exception (file, e);
- }
- }
- void
- exception_fprintf (struct ui_file *file, const struct gdb_exception &e,
- const char *prefix, ...)
- {
- if (e.reason < 0 && e.message != NULL)
- {
- va_list args;
- print_flush ();
- /* Print the prefix. */
- va_start (args, prefix);
- gdb_vprintf (file, prefix, args);
- va_end (args);
- print_exception (file, e);
- }
- }
|