1 /* Exception (throw catch) mechanism, for GDB, the GNU debugger. 2 3 Copyright (C) 1986-2020 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 3 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 _filtered buffer. */ 54 if (filtered_printing_initialized ()) 55 wrap_here (""); 56 57 /* 2. The stdio buffer. */ 58 gdb_flush (gdb_stdout); 59 gdb_flush (gdb_stderr); 60 61 /* 3. The system-level buffer. */ 62 gdb_stdout_serial = serial_fdopen (fileno (ui->outstream)); 63 if (gdb_stdout_serial) 64 { 65 serial_drain_output (gdb_stdout_serial); 66 serial_un_fdopen (gdb_stdout_serial); 67 } 68 69 annotate_error_begin (); 70 } 71 72 static void 73 print_exception (struct ui_file *file, const struct gdb_exception &e) 74 { 75 /* KLUDGE: cagney/2005-01-13: Write the string out one line at a time 76 as that way the MI's behavior is preserved. */ 77 const char *start; 78 const char *end; 79 80 for (start = e.what (); start != NULL; start = end) 81 { 82 end = strchr (start, '\n'); 83 if (end == NULL) 84 fputs_filtered (start, file); 85 else 86 { 87 end++; 88 file->write (start, end - start); 89 } 90 } 91 fprintf_filtered (file, "\n"); 92 93 /* Now append the annotation. */ 94 switch (e.reason) 95 { 96 case RETURN_QUIT: 97 annotate_quit (); 98 break; 99 case RETURN_ERROR: 100 /* Assume that these are all errors. */ 101 annotate_error (); 102 break; 103 default: 104 internal_error (__FILE__, __LINE__, _("Bad switch.")); 105 } 106 } 107 108 void 109 exception_print (struct ui_file *file, const struct gdb_exception &e) 110 { 111 if (e.reason < 0 && e.message != NULL) 112 { 113 print_flush (); 114 print_exception (file, e); 115 } 116 } 117 118 void 119 exception_fprintf (struct ui_file *file, const struct gdb_exception &e, 120 const char *prefix, ...) 121 { 122 if (e.reason < 0 && e.message != NULL) 123 { 124 va_list args; 125 126 print_flush (); 127 128 /* Print the prefix. */ 129 va_start (args, prefix); 130 vfprintf_filtered (file, prefix, args); 131 va_end (args); 132 133 print_exception (file, e); 134 } 135 } 136 137 /* See exceptions.h. */ 138 139 int 140 exception_print_same (const struct gdb_exception &e1, 141 const struct gdb_exception &e2) 142 { 143 const char *msg1 = e1.message == nullptr ? "" : e1.what (); 144 const char *msg2 = e2.message == nullptr ? "" : e2.what (); 145 146 return (e1.reason == e2.reason 147 && e1.error == e2.error 148 && strcmp (msg1, msg2) == 0); 149 } 150