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