1 /* Exception (throw catch) mechanism, for GDB, the GNU debugger. 2 3 Copyright (C) 1986-2023 Free Software Foundation, Inc. 4 5 This file is part of GDB. 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include "defs.h" 21 #include "exceptions.h" 22 #include "breakpoint.h" 23 #include "target.h" 24 #include "inferior.h" 25 #include "annotate.h" 26 #include "ui-out.h" 27 #include "serial.h" 28 #include "gdbthread.h" 29 #include "top.h" 30 #include "gdbsupport/gdb_optional.h" 31 32 static void 33 print_flush (void) 34 { 35 struct ui *ui = current_ui; 36 struct serial *gdb_stdout_serial; 37 38 if (deprecated_error_begin_hook) 39 deprecated_error_begin_hook (); 40 41 gdb::optional<target_terminal::scoped_restore_terminal_state> term_state; 42 if (target_supports_terminal_ours ()) 43 { 44 term_state.emplace (); 45 target_terminal::ours_for_output (); 46 } 47 48 /* We want all output to appear now, before we print the error. We 49 have 2 levels of buffering we have to flush (it's possible that 50 some of these should be changed to flush the lower-level ones 51 too): */ 52 53 /* 1. The stdio buffer. */ 54 gdb_flush (gdb_stdout); 55 gdb_flush (gdb_stderr); 56 57 /* 2. The system-level buffer. */ 58 gdb_stdout_serial = serial_fdopen (fileno (ui->outstream)); 59 if (gdb_stdout_serial) 60 { 61 serial_drain_output (gdb_stdout_serial); 62 serial_un_fdopen (gdb_stdout_serial); 63 } 64 65 annotate_error_begin (); 66 } 67 68 static void 69 print_exception (struct ui_file *file, const struct gdb_exception &e) 70 { 71 /* KLUDGE: cagney/2005-01-13: Write the string out one line at a time 72 as that way the MI's behavior is preserved. */ 73 const char *start; 74 const char *end; 75 76 for (start = e.what (); start != NULL; start = end) 77 { 78 end = strchr (start, '\n'); 79 if (end == NULL) 80 gdb_puts (start, file); 81 else 82 { 83 end++; 84 file->write (start, end - start); 85 } 86 } 87 gdb_printf (file, "\n"); 88 89 /* Now append the annotation. */ 90 switch (e.reason) 91 { 92 case RETURN_QUIT: 93 annotate_quit (); 94 break; 95 case RETURN_ERROR: 96 /* Assume that these are all errors. */ 97 annotate_error (); 98 break; 99 default: 100 internal_error (_("Bad switch.")); 101 } 102 } 103 104 void 105 exception_print (struct ui_file *file, const struct gdb_exception &e) 106 { 107 if (e.reason < 0 && e.message != NULL) 108 { 109 print_flush (); 110 print_exception (file, e); 111 } 112 } 113 114 void 115 exception_fprintf (struct ui_file *file, const struct gdb_exception &e, 116 const char *prefix, ...) 117 { 118 if (e.reason < 0 && e.message != NULL) 119 { 120 va_list args; 121 122 print_flush (); 123 124 /* Print the prefix. */ 125 va_start (args, prefix); 126 gdb_vprintf (file, prefix, args); 127 va_end (args); 128 129 print_exception (file, e); 130 } 131 } 132