]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/exceptions.c
Make input_fd be per UI
[thirdparty/binutils-gdb.git] / gdb / exceptions.c
CommitLineData
60250e8b
AC
1/* Exception (throw catch) mechanism, for GDB, the GNU debugger.
2
618f726f 3 Copyright (C) 1986-2016 Free Software Foundation, Inc.
60250e8b
AC
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
60250e8b
AC
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
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
60250e8b
AC
19
20#include "defs.h"
21#include "exceptions.h"
60250e8b
AC
22#include "breakpoint.h"
23#include "target.h"
24#include "inferior.h"
25#include "annotate.h"
26#include "ui-out.h"
e06e2353 27#include "serial.h"
347bddb7 28#include "gdbthread.h"
60250e8b 29
6b1b7650 30static void
c6da7a6d 31print_flush (void)
6b1b7650 32{
e06e2353 33 struct serial *gdb_stdout_serial;
481ac8c9 34 struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
e06e2353 35
c6da7a6d
AC
36 if (deprecated_error_begin_hook)
37 deprecated_error_begin_hook ();
5df43998
GB
38
39 if (target_supports_terminal_ours ())
481ac8c9
PA
40 {
41 make_cleanup_restore_target_terminal ();
42 target_terminal_ours_for_output ();
43 }
e06e2353
AC
44
45 /* We want all output to appear now, before we print the error. We
46 have 3 levels of buffering we have to flush (it's possible that
47 some of these should be changed to flush the lower-level ones
48 too): */
49
50 /* 1. The _filtered buffer. */
5df43998
GB
51 if (filtered_printing_initialized ())
52 wrap_here ("");
e06e2353
AC
53
54 /* 2. The stdio buffer. */
c6da7a6d 55 gdb_flush (gdb_stdout);
e06e2353
AC
56 gdb_flush (gdb_stderr);
57
58 /* 3. The system-level buffer. */
59 gdb_stdout_serial = serial_fdopen (1);
cade9e54
PB
60 if (gdb_stdout_serial)
61 {
62 serial_drain_output (gdb_stdout_serial);
63 serial_un_fdopen (gdb_stdout_serial);
64 }
e06e2353 65
c6da7a6d 66 annotate_error_begin ();
481ac8c9
PA
67
68 do_cleanups (old_chain);
6b1b7650
AC
69}
70
9cbc821d 71static void
71fff37b 72print_exception (struct ui_file *file, struct gdb_exception e)
9cbc821d
AC
73{
74 /* KLUGE: cagney/2005-01-13: Write the string out one line at a time
75 as that way the MI's behavior is preserved. */
76 const char *start;
77 const char *end;
d7f9d729 78
9cbc821d
AC
79 for (start = e.message; start != NULL; start = end)
80 {
81 end = strchr (start, '\n');
82 if (end == NULL)
83 fputs_filtered (start, file);
84 else
85 {
86 end++;
87 ui_file_write (file, start, end - start);
88 }
89 }
c6da7a6d 90 fprintf_filtered (file, "\n");
e48f5bee
AC
91
92 /* Now append the annotation. */
93 switch (e.reason)
94 {
95 case RETURN_QUIT:
96 annotate_quit ();
97 break;
98 case RETURN_ERROR:
99 /* Assume that these are all errors. */
100 annotate_error ();
101 break;
102 default:
103 internal_error (__FILE__, __LINE__, _("Bad switch."));
104 }
9cbc821d
AC
105}
106
8a076db9 107void
71fff37b 108exception_print (struct ui_file *file, struct gdb_exception e)
8a076db9
AC
109{
110 if (e.reason < 0 && e.message != NULL)
111 {
c6da7a6d 112 print_flush ();
9cbc821d 113 print_exception (file, e);
9cbc821d
AC
114 }
115}
8a076db9 116
9cbc821d 117void
71fff37b 118exception_fprintf (struct ui_file *file, struct gdb_exception e,
9cbc821d
AC
119 const char *prefix, ...)
120{
121 if (e.reason < 0 && e.message != NULL)
122 {
123 va_list args;
c6da7a6d
AC
124
125 print_flush ();
9cbc821d
AC
126
127 /* Print the prefix. */
128 va_start (args, prefix);
129 vfprintf_filtered (file, prefix, args);
130 va_end (args);
131
132 print_exception (file, e);
8a076db9
AC
133 }
134}
135
787274f0
DE
136/* Call FUNC(UIOUT, FUNC_ARGS) but wrapped within an exception
137 handler. If an exception (enum return_reason) is thrown using
138 throw_exception() than all cleanups installed since
139 catch_exceptions() was entered are invoked, the (-ve) exception
140 value is then returned by catch_exceptions. If FUNC() returns
141 normally (with a positive or zero return value) then that value is
142 returned by catch_exceptions(). It is an internal_error() for
143 FUNC() to return a negative value.
144
585a46a2 145 See exceptions.h for further usage details. */
60250e8b
AC
146
147/* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with
7a9dd1b2 148 error() et al. could maintain a set of flags that indicate the
60250e8b
AC
149 current state of each of the longjmp buffers. This would give the
150 longjmp code the chance to detect a longjmp botch (before it gets
151 to longjmperror()). Prior to 1999-11-05 this wasn't possible as
152 code also randomly used a SET_TOP_LEVEL macro that directly
0963b4bd 153 initialized the longjmp buffers. */
60250e8b 154
60250e8b
AC
155int
156catch_exceptions (struct ui_out *uiout,
157 catch_exceptions_ftype *func,
158 void *func_args,
60250e8b
AC
159 return_mask mask)
160{
1c3c7ee7 161 return catch_exceptions_with_msg (uiout, func, func_args, NULL, mask);
60250e8b
AC
162}
163
164int
f9679975 165catch_exceptions_with_msg (struct ui_out *func_uiout,
60250e8b
AC
166 catch_exceptions_ftype *func,
167 void *func_args,
60250e8b
AC
168 char **gdberrmsg,
169 return_mask mask)
170{
7556d4a4 171 struct gdb_exception exception = exception_none;
2a78bfb5 172 volatile int val = 0;
f9679975 173 struct ui_out *saved_uiout;
d7f9d729 174
f9679975 175 /* Save and override the global ``struct ui_out'' builder. */
79a45e25
PA
176 saved_uiout = current_uiout;
177 current_uiout = func_uiout;
f9679975 178
492d29ea 179 TRY
6941d02a 180 {
79a45e25 181 val = (*func) (current_uiout, func_args);
6941d02a 182 }
492d29ea 183 CATCH (ex, RETURN_MASK_ALL)
7556d4a4
PA
184 {
185 exception = ex;
186 }
492d29ea 187 END_CATCH
f9679975
PA
188
189 /* Restore the global builder. */
79a45e25 190 current_uiout = saved_uiout;
f9679975
PA
191
192 if (exception.reason < 0 && (mask & RETURN_MASK (exception.reason)) == 0)
193 {
194 /* The caller didn't request that the event be caught.
195 Rethrow. */
196 throw_exception (exception);
197 }
198
feefc97b 199 exception_print (gdb_stderr, exception);
60250e8b 200 gdb_assert (val >= 0);
2a78bfb5
AC
201 gdb_assert (exception.reason <= 0);
202 if (exception.reason < 0)
203 {
204 /* If caller wants a copy of the low-level error message, make
205 one. This is used in the case of a silent error whereby the
206 caller may optionally want to issue the message. */
207 if (gdberrmsg != NULL)
6b1b7650
AC
208 {
209 if (exception.message != NULL)
210 *gdberrmsg = xstrdup (exception.message);
211 else
212 *gdberrmsg = NULL;
213 }
2a78bfb5
AC
214 return exception.reason;
215 }
60250e8b
AC
216 return val;
217}
218
787274f0
DE
219/* This function is superseded by catch_exceptions(). */
220
60250e8b
AC
221int
222catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
223 return_mask mask)
224{
492d29ea 225 struct gdb_exception exception = exception_none;
2a78bfb5 226 volatile int val = 0;
f9679975 227 struct ui_out *saved_uiout;
d7f9d729 228
f9679975 229 /* Save the global ``struct ui_out'' builder. */
79a45e25 230 saved_uiout = current_uiout;
f9679975 231
492d29ea 232 TRY
6941d02a
AC
233 {
234 val = func (func_args);
235 }
492d29ea
PA
236 CATCH (ex, RETURN_MASK_ALL)
237 {
238 exception = ex;
239 }
240 END_CATCH
f9679975
PA
241
242 /* Restore the global builder. */
79a45e25 243 current_uiout = saved_uiout;
f9679975
PA
244
245 if (exception.reason < 0 && (mask & RETURN_MASK (exception.reason)) == 0)
246 {
247 /* The caller didn't request that the event be caught.
248 Rethrow. */
249 throw_exception (exception);
250 }
251
feefc97b 252 exception_fprintf (gdb_stderr, exception, "%s", errstring);
2a78bfb5 253 if (exception.reason != 0)
60250e8b
AC
254 return 0;
255 return val;
256}