Imported Upstream version 7.9
[platform/upstream/gdb.git] / gdb / exceptions.c
1 /* Exception (throw catch) mechanism, for GDB, the GNU debugger.
2
3    Copyright (C) 1986-2015 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 const struct gdb_exception exception_none = { 0, GDB_NO_ERROR, NULL };
31
32 void
33 prepare_to_throw_exception (void)
34 {
35   clear_quit_flag ();
36   immediate_quit = 0;
37 }
38
39 static void
40 print_flush (void)
41 {
42   struct serial *gdb_stdout_serial;
43
44   if (deprecated_error_begin_hook)
45     deprecated_error_begin_hook ();
46
47   if (target_supports_terminal_ours ())
48     target_terminal_ours ();
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.  */
56   if (filtered_printing_initialized ())
57     wrap_here ("");
58
59   /* 2.  The stdio buffer.  */
60   gdb_flush (gdb_stdout);
61   gdb_flush (gdb_stderr);
62
63   /* 3.  The system-level buffer.  */
64   gdb_stdout_serial = serial_fdopen (1);
65   if (gdb_stdout_serial)
66     {
67       serial_drain_output (gdb_stdout_serial);
68       serial_un_fdopen (gdb_stdout_serial);
69     }
70
71   annotate_error_begin ();
72 }
73
74 static void
75 print_exception (struct ui_file *file, struct gdb_exception e)
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;
81
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     }                                       
93   fprintf_filtered (file, "\n");
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     }
108 }
109
110 void
111 exception_print (struct ui_file *file, struct gdb_exception e)
112 {
113   if (e.reason < 0 && e.message != NULL)
114     {
115       print_flush ();
116       print_exception (file, e);
117     }
118 }
119
120 void
121 exception_fprintf (struct ui_file *file, struct gdb_exception e,
122                    const char *prefix, ...)
123 {
124   if (e.reason < 0 && e.message != NULL)
125     {
126       va_list args;
127
128       print_flush ();
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);
136     }
137 }
138
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.
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
153    be replaced by judicious use of QUIT.  */
154
155 /* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with
156    error() et al. could maintain a set of flags that indicate the
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
161    initialized the longjmp buffers.  */
162
163 int
164 catch_exceptions (struct ui_out *uiout,
165                   catch_exceptions_ftype *func,
166                   void *func_args,
167                   return_mask mask)
168 {
169   return catch_exceptions_with_msg (uiout, func, func_args, NULL, mask);
170 }
171
172 int
173 catch_exceptions_with_msg (struct ui_out *func_uiout,
174                            catch_exceptions_ftype *func,
175                            void *func_args,
176                            char **gdberrmsg,
177                            return_mask mask)
178 {
179   volatile struct gdb_exception exception;
180   volatile int val = 0;
181   struct ui_out *saved_uiout;
182
183   /* Save and override the global ``struct ui_out'' builder.  */
184   saved_uiout = current_uiout;
185   current_uiout = func_uiout;
186
187   TRY_CATCH (exception, RETURN_MASK_ALL)
188     {
189       val = (*func) (current_uiout, func_args);
190     }
191
192   /* Restore the global builder.  */
193   current_uiout = saved_uiout;
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
202   exception_print (gdb_stderr, exception);
203   gdb_assert (val >= 0);
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)
211         {
212           if (exception.message != NULL)
213             *gdberrmsg = xstrdup (exception.message);
214           else
215             *gdberrmsg = NULL;
216         }
217       return exception.reason;
218     }
219   return val;
220 }
221
222 /* This function is superseded by catch_exceptions().  */
223
224 int
225 catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
226               return_mask mask)
227 {
228   volatile int val = 0;
229   volatile struct gdb_exception exception;
230   struct ui_out *saved_uiout;
231
232   /* Save the global ``struct ui_out'' builder.  */
233   saved_uiout = current_uiout;
234
235   TRY_CATCH (exception, RETURN_MASK_ALL)
236     {
237       val = func (func_args);
238     }
239
240   /* Restore the global builder.  */
241   current_uiout = saved_uiout;
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
250   exception_fprintf (gdb_stderr, exception, "%s", errstring);
251   if (exception.reason != 0)
252     return 0;
253   return val;
254 }