0e600504c1af599c3891db4a7a25914008013a4c
[external/binutils.git] / gdb / exceptions.c
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
30 static void
31 print_flush (void)
32 {
33   struct serial *gdb_stdout_serial;
34   struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
35
36   if (deprecated_error_begin_hook)
37     deprecated_error_begin_hook ();
38
39   if (target_supports_terminal_ours ())
40     {
41       make_cleanup_restore_target_terminal ();
42       target_terminal_ours_for_output ();
43     }
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.  */
51   if (filtered_printing_initialized ())
52     wrap_here ("");
53
54   /* 2.  The stdio buffer.  */
55   gdb_flush (gdb_stdout);
56   gdb_flush (gdb_stderr);
57
58   /* 3.  The system-level buffer.  */
59   gdb_stdout_serial = serial_fdopen (1);
60   if (gdb_stdout_serial)
61     {
62       serial_drain_output (gdb_stdout_serial);
63       serial_un_fdopen (gdb_stdout_serial);
64     }
65
66   annotate_error_begin ();
67
68   do_cleanups (old_chain);
69 }
70
71 static void
72 print_exception (struct ui_file *file, struct gdb_exception e)
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;
78
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     }                                       
90   fprintf_filtered (file, "\n");
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     }
105 }
106
107 void
108 exception_print (struct ui_file *file, struct gdb_exception e)
109 {
110   if (e.reason < 0 && e.message != NULL)
111     {
112       print_flush ();
113       print_exception (file, e);
114     }
115 }
116
117 void
118 exception_fprintf (struct ui_file *file, struct gdb_exception e,
119                    const char *prefix, ...)
120 {
121   if (e.reason < 0 && e.message != NULL)
122     {
123       va_list args;
124
125       print_flush ();
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);
133     }
134 }
135
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
145    See exceptions.h for further usage details.  */
146
147 /* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with
148    error() et al. could maintain a set of flags that indicate the
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
153    initialized the longjmp buffers.  */
154
155 int
156 catch_exceptions (struct ui_out *uiout,
157                   catch_exceptions_ftype *func,
158                   void *func_args,
159                   return_mask mask)
160 {
161   return catch_exceptions_with_msg (uiout, func, func_args, NULL, mask);
162 }
163
164 int
165 catch_exceptions_with_msg (struct ui_out *func_uiout,
166                            catch_exceptions_ftype *func,
167                            void *func_args,
168                            char **gdberrmsg,
169                            return_mask mask)
170 {
171   struct gdb_exception exception = exception_none;
172   volatile int val = 0;
173   struct ui_out *saved_uiout;
174
175   /* Save and override the global ``struct ui_out'' builder.  */
176   saved_uiout = current_uiout;
177   current_uiout = func_uiout;
178
179   TRY
180     {
181       val = (*func) (current_uiout, func_args);
182     }
183   CATCH (ex, RETURN_MASK_ALL)
184     {
185       exception = ex;
186     }
187   END_CATCH
188
189   /* Restore the global builder.  */
190   current_uiout = saved_uiout;
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
199   exception_print (gdb_stderr, exception);
200   gdb_assert (val >= 0);
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)
208         {
209           if (exception.message != NULL)
210             *gdberrmsg = xstrdup (exception.message);
211           else
212             *gdberrmsg = NULL;
213         }
214       return exception.reason;
215     }
216   return val;
217 }
218
219 /* This function is superseded by catch_exceptions().  */
220
221 int
222 catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
223               return_mask mask)
224 {
225   struct gdb_exception exception = exception_none;
226   volatile int val = 0;
227   struct ui_out *saved_uiout;
228
229   /* Save the global ``struct ui_out'' builder.  */
230   saved_uiout = current_uiout;
231
232   TRY
233     {
234       val = func (func_args);
235     }
236   CATCH (ex, RETURN_MASK_ALL)
237     {
238       exception = ex;
239     }
240   END_CATCH
241
242   /* Restore the global builder.  */
243   current_uiout = saved_uiout;
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
252   exception_fprintf (gdb_stderr, exception, "%s", errstring);
253   if (exception.reason != 0)
254     return 0;
255   return val;
256 }