target remote: Don't rely on immediate_quit (introduce quit handlers)
[deliverable/binutils-gdb.git] / gdb / exceptions.c
... / ...
CommitLineData
1/* Exception (throw catch) mechanism, for GDB, the GNU debugger.
2
3 Copyright (C) 1986-2016 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
30void
31prepare_to_throw_exception (void)
32{
33 immediate_quit = 0;
34}
35
36static void
37print_flush (void)
38{
39 struct serial *gdb_stdout_serial;
40 struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
41
42 if (deprecated_error_begin_hook)
43 deprecated_error_begin_hook ();
44
45 if (target_supports_terminal_ours ())
46 {
47 make_cleanup_restore_target_terminal ();
48 target_terminal_ours_for_output ();
49 }
50
51 /* We want all output to appear now, before we print the error. We
52 have 3 levels of buffering we have to flush (it's possible that
53 some of these should be changed to flush the lower-level ones
54 too): */
55
56 /* 1. The _filtered buffer. */
57 if (filtered_printing_initialized ())
58 wrap_here ("");
59
60 /* 2. The stdio buffer. */
61 gdb_flush (gdb_stdout);
62 gdb_flush (gdb_stderr);
63
64 /* 3. The system-level buffer. */
65 gdb_stdout_serial = serial_fdopen (1);
66 if (gdb_stdout_serial)
67 {
68 serial_drain_output (gdb_stdout_serial);
69 serial_un_fdopen (gdb_stdout_serial);
70 }
71
72 annotate_error_begin ();
73
74 do_cleanups (old_chain);
75}
76
77static void
78print_exception (struct ui_file *file, struct gdb_exception e)
79{
80 /* KLUGE: cagney/2005-01-13: Write the string out one line at a time
81 as that way the MI's behavior is preserved. */
82 const char *start;
83 const char *end;
84
85 for (start = e.message; start != NULL; start = end)
86 {
87 end = strchr (start, '\n');
88 if (end == NULL)
89 fputs_filtered (start, file);
90 else
91 {
92 end++;
93 ui_file_write (file, start, end - start);
94 }
95 }
96 fprintf_filtered (file, "\n");
97
98 /* Now append the annotation. */
99 switch (e.reason)
100 {
101 case RETURN_QUIT:
102 annotate_quit ();
103 break;
104 case RETURN_ERROR:
105 /* Assume that these are all errors. */
106 annotate_error ();
107 break;
108 default:
109 internal_error (__FILE__, __LINE__, _("Bad switch."));
110 }
111}
112
113void
114exception_print (struct ui_file *file, struct gdb_exception e)
115{
116 if (e.reason < 0 && e.message != NULL)
117 {
118 print_flush ();
119 print_exception (file, e);
120 }
121}
122
123void
124exception_fprintf (struct ui_file *file, struct gdb_exception e,
125 const char *prefix, ...)
126{
127 if (e.reason < 0 && e.message != NULL)
128 {
129 va_list args;
130
131 print_flush ();
132
133 /* Print the prefix. */
134 va_start (args, prefix);
135 vfprintf_filtered (file, prefix, args);
136 va_end (args);
137
138 print_exception (file, e);
139 }
140}
141
142/* Call FUNC(UIOUT, FUNC_ARGS) but wrapped within an exception
143 handler. If an exception (enum return_reason) is thrown using
144 throw_exception() than all cleanups installed since
145 catch_exceptions() was entered are invoked, the (-ve) exception
146 value is then returned by catch_exceptions. If FUNC() returns
147 normally (with a positive or zero return value) then that value is
148 returned by catch_exceptions(). It is an internal_error() for
149 FUNC() to return a negative value.
150
151 See exceptions.h for further usage details.
152
153 Must not be called with immediate_quit in effect (bad things might
154 happen, say we got a signal in the middle of a memcpy to quit_return).
155 This is an OK restriction; with very few exceptions immediate_quit can
156 be replaced by judicious use of QUIT. */
157
158/* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with
159 error() et al. could maintain a set of flags that indicate the
160 current state of each of the longjmp buffers. This would give the
161 longjmp code the chance to detect a longjmp botch (before it gets
162 to longjmperror()). Prior to 1999-11-05 this wasn't possible as
163 code also randomly used a SET_TOP_LEVEL macro that directly
164 initialized the longjmp buffers. */
165
166int
167catch_exceptions (struct ui_out *uiout,
168 catch_exceptions_ftype *func,
169 void *func_args,
170 return_mask mask)
171{
172 return catch_exceptions_with_msg (uiout, func, func_args, NULL, mask);
173}
174
175int
176catch_exceptions_with_msg (struct ui_out *func_uiout,
177 catch_exceptions_ftype *func,
178 void *func_args,
179 char **gdberrmsg,
180 return_mask mask)
181{
182 struct gdb_exception exception = exception_none;
183 volatile int val = 0;
184 struct ui_out *saved_uiout;
185
186 /* Save and override the global ``struct ui_out'' builder. */
187 saved_uiout = current_uiout;
188 current_uiout = func_uiout;
189
190 TRY
191 {
192 val = (*func) (current_uiout, func_args);
193 }
194 CATCH (ex, RETURN_MASK_ALL)
195 {
196 exception = ex;
197 }
198 END_CATCH
199
200 /* Restore the global builder. */
201 current_uiout = saved_uiout;
202
203 if (exception.reason < 0 && (mask & RETURN_MASK (exception.reason)) == 0)
204 {
205 /* The caller didn't request that the event be caught.
206 Rethrow. */
207 throw_exception (exception);
208 }
209
210 exception_print (gdb_stderr, exception);
211 gdb_assert (val >= 0);
212 gdb_assert (exception.reason <= 0);
213 if (exception.reason < 0)
214 {
215 /* If caller wants a copy of the low-level error message, make
216 one. This is used in the case of a silent error whereby the
217 caller may optionally want to issue the message. */
218 if (gdberrmsg != NULL)
219 {
220 if (exception.message != NULL)
221 *gdberrmsg = xstrdup (exception.message);
222 else
223 *gdberrmsg = NULL;
224 }
225 return exception.reason;
226 }
227 return val;
228}
229
230/* This function is superseded by catch_exceptions(). */
231
232int
233catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
234 return_mask mask)
235{
236 struct gdb_exception exception = exception_none;
237 volatile int val = 0;
238 struct ui_out *saved_uiout;
239
240 /* Save the global ``struct ui_out'' builder. */
241 saved_uiout = current_uiout;
242
243 TRY
244 {
245 val = func (func_args);
246 }
247 CATCH (ex, RETURN_MASK_ALL)
248 {
249 exception = ex;
250 }
251 END_CATCH
252
253 /* Restore the global builder. */
254 current_uiout = saved_uiout;
255
256 if (exception.reason < 0 && (mask & RETURN_MASK (exception.reason)) == 0)
257 {
258 /* The caller didn't request that the event be caught.
259 Rethrow. */
260 throw_exception (exception);
261 }
262
263 exception_fprintf (gdb_stderr, exception, "%s", errstring);
264 if (exception.reason != 0)
265 return 0;
266 return val;
267}
This page took 0.027969 seconds and 4 git commands to generate.