Change arm_objfile_data_key to use type-safe registry
[external/binutils.git] / gdb / exceptions.c
1 /* Exception (throw catch) mechanism, for GDB, the GNU debugger.
2
3    Copyright (C) 1986-2019 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 "common/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   /* While normally there's always something pushed on the target
43      stack, the NULL check is needed here because we can get here very
44      early during startup, before the target stack is first
45      initialized.  */
46   if (current_top_target () != NULL && target_supports_terminal_ours ())
47     {
48       term_state.emplace ();
49       target_terminal::ours_for_output ();
50     }
51
52   /* We want all output to appear now, before we print the error.  We
53      have 3 levels of buffering we have to flush (it's possible that
54      some of these should be changed to flush the lower-level ones
55      too):  */
56
57   /* 1.  The _filtered buffer.  */
58   if (filtered_printing_initialized ())
59     wrap_here ("");
60
61   /* 2.  The stdio buffer.  */
62   gdb_flush (gdb_stdout);
63   gdb_flush (gdb_stderr);
64
65   /* 3.  The system-level buffer.  */
66   gdb_stdout_serial = serial_fdopen (fileno (ui->outstream));
67   if (gdb_stdout_serial)
68     {
69       serial_drain_output (gdb_stdout_serial);
70       serial_un_fdopen (gdb_stdout_serial);
71     }
72
73   annotate_error_begin ();
74 }
75
76 static void
77 print_exception (struct ui_file *file, const struct gdb_exception &e)
78 {
79   /* KLUGE: cagney/2005-01-13: Write the string out one line at a time
80      as that way the MI's behavior is preserved.  */
81   const char *start;
82   const char *end;
83
84   for (start = e.what (); start != NULL; start = end)
85     {
86       end = strchr (start, '\n');
87       if (end == NULL)
88         fputs_filtered (start, file);
89       else
90         {
91           end++;
92           ui_file_write (file, start, end - start);
93         }
94     }                                       
95   fprintf_filtered (file, "\n");
96
97   /* Now append the annotation.  */
98   switch (e.reason)
99     {
100     case RETURN_QUIT:
101       annotate_quit ();
102       break;
103     case RETURN_ERROR:
104       /* Assume that these are all errors.  */
105       annotate_error ();
106       break;
107     default:
108       internal_error (__FILE__, __LINE__, _("Bad switch."));
109     }
110 }
111
112 void
113 exception_print (struct ui_file *file, const struct gdb_exception &e)
114 {
115   if (e.reason < 0 && e.message != NULL)
116     {
117       print_flush ();
118       print_exception (file, e);
119     }
120 }
121
122 void
123 exception_fprintf (struct ui_file *file, const struct gdb_exception &e,
124                    const char *prefix, ...)
125 {
126   if (e.reason < 0 && e.message != NULL)
127     {
128       va_list args;
129
130       print_flush ();
131
132       /* Print the prefix.  */
133       va_start (args, prefix);
134       vfprintf_filtered (file, prefix, args);
135       va_end (args);
136
137       print_exception (file, e);
138     }
139 }
140
141 /* See exceptions.h.  */
142
143 int
144 exception_print_same (const struct gdb_exception &e1,
145                       const struct gdb_exception &e2)
146 {
147   const char *msg1 = e1.message == nullptr ? "" : e1.what ();
148   const char *msg2 = e2.message == nullptr ? "" : e2.what ();
149
150   return (e1.reason == e2.reason
151           && e1.error == e2.error
152           && strcmp (msg1, msg2) == 0);
153 }