xref: /dragonfly/contrib/gdb-7/gdb/exceptions.c (revision c50c785c)
15796c8dcSSimon Schubert /* Exception (throw catch) mechanism, for GDB, the GNU debugger.
25796c8dcSSimon Schubert 
35796c8dcSSimon Schubert    Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
45796c8dcSSimon Schubert    1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
5*c50c785cSJohn Marino    2009, 2010, 2011 Free Software Foundation, Inc.
65796c8dcSSimon Schubert 
75796c8dcSSimon Schubert    This file is part of GDB.
85796c8dcSSimon Schubert 
95796c8dcSSimon Schubert    This program is free software; you can redistribute it and/or modify
105796c8dcSSimon Schubert    it under the terms of the GNU General Public License as published by
115796c8dcSSimon Schubert    the Free Software Foundation; either version 3 of the License, or
125796c8dcSSimon Schubert    (at your option) any later version.
135796c8dcSSimon Schubert 
145796c8dcSSimon Schubert    This program is distributed in the hope that it will be useful,
155796c8dcSSimon Schubert    but WITHOUT ANY WARRANTY; without even the implied warranty of
165796c8dcSSimon Schubert    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
175796c8dcSSimon Schubert    GNU General Public License for more details.
185796c8dcSSimon Schubert 
195796c8dcSSimon Schubert    You should have received a copy of the GNU General Public License
205796c8dcSSimon Schubert    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
215796c8dcSSimon Schubert 
225796c8dcSSimon Schubert #include "defs.h"
235796c8dcSSimon Schubert #include "exceptions.h"
245796c8dcSSimon Schubert #include "breakpoint.h"
255796c8dcSSimon Schubert #include "target.h"
265796c8dcSSimon Schubert #include "inferior.h"
275796c8dcSSimon Schubert #include "annotate.h"
285796c8dcSSimon Schubert #include "ui-out.h"
295796c8dcSSimon Schubert #include "gdb_assert.h"
305796c8dcSSimon Schubert #include "gdb_string.h"
315796c8dcSSimon Schubert #include "serial.h"
325796c8dcSSimon Schubert #include "gdbthread.h"
335796c8dcSSimon Schubert 
345796c8dcSSimon Schubert const struct gdb_exception exception_none = { 0, GDB_NO_ERROR, NULL };
355796c8dcSSimon Schubert 
365796c8dcSSimon Schubert /* Possible catcher states.  */
375796c8dcSSimon Schubert enum catcher_state {
385796c8dcSSimon Schubert   /* Initial state, a new catcher has just been created.  */
395796c8dcSSimon Schubert   CATCHER_CREATED,
405796c8dcSSimon Schubert   /* The catch code is running.  */
415796c8dcSSimon Schubert   CATCHER_RUNNING,
425796c8dcSSimon Schubert   CATCHER_RUNNING_1,
435796c8dcSSimon Schubert   /* The catch code threw an exception.  */
445796c8dcSSimon Schubert   CATCHER_ABORTING
455796c8dcSSimon Schubert };
465796c8dcSSimon Schubert 
475796c8dcSSimon Schubert /* Possible catcher actions.  */
485796c8dcSSimon Schubert enum catcher_action {
495796c8dcSSimon Schubert   CATCH_ITER,
505796c8dcSSimon Schubert   CATCH_ITER_1,
515796c8dcSSimon Schubert   CATCH_THROWING
525796c8dcSSimon Schubert };
535796c8dcSSimon Schubert 
545796c8dcSSimon Schubert struct catcher
555796c8dcSSimon Schubert {
565796c8dcSSimon Schubert   enum catcher_state state;
575796c8dcSSimon Schubert   /* Jump buffer pointing back at the exception handler.  */
585796c8dcSSimon Schubert   EXCEPTIONS_SIGJMP_BUF buf;
595796c8dcSSimon Schubert   /* Status buffer belonging to the exception handler.  */
605796c8dcSSimon Schubert   volatile struct gdb_exception *exception;
615796c8dcSSimon Schubert   /* Saved/current state.  */
625796c8dcSSimon Schubert   int mask;
635796c8dcSSimon Schubert   struct ui_out *saved_uiout;
645796c8dcSSimon Schubert   struct cleanup *saved_cleanup_chain;
655796c8dcSSimon Schubert   /* Back link.  */
665796c8dcSSimon Schubert   struct catcher *prev;
675796c8dcSSimon Schubert };
685796c8dcSSimon Schubert 
695796c8dcSSimon Schubert /* Where to go for throw_exception().  */
705796c8dcSSimon Schubert static struct catcher *current_catcher;
715796c8dcSSimon Schubert 
725796c8dcSSimon Schubert EXCEPTIONS_SIGJMP_BUF *
735796c8dcSSimon Schubert exceptions_state_mc_init (struct ui_out *func_uiout,
745796c8dcSSimon Schubert 			  volatile struct gdb_exception *exception,
755796c8dcSSimon Schubert 			  return_mask mask)
765796c8dcSSimon Schubert {
775796c8dcSSimon Schubert   struct catcher *new_catcher = XZALLOC (struct catcher);
785796c8dcSSimon Schubert 
795796c8dcSSimon Schubert   /* Start with no exception, save it's address.  */
805796c8dcSSimon Schubert   exception->reason = 0;
815796c8dcSSimon Schubert   exception->error = GDB_NO_ERROR;
825796c8dcSSimon Schubert   exception->message = NULL;
835796c8dcSSimon Schubert   new_catcher->exception = exception;
845796c8dcSSimon Schubert 
855796c8dcSSimon Schubert   new_catcher->mask = mask;
865796c8dcSSimon Schubert 
875796c8dcSSimon Schubert   /* Override the global ``struct ui_out'' builder.  */
885796c8dcSSimon Schubert   new_catcher->saved_uiout = uiout;
895796c8dcSSimon Schubert   uiout = func_uiout;
905796c8dcSSimon Schubert 
915796c8dcSSimon Schubert   /* Prevent error/quit during FUNC from calling cleanups established
925796c8dcSSimon Schubert      prior to here.  */
935796c8dcSSimon Schubert   new_catcher->saved_cleanup_chain = save_cleanups ();
945796c8dcSSimon Schubert 
955796c8dcSSimon Schubert   /* Push this new catcher on the top.  */
965796c8dcSSimon Schubert   new_catcher->prev = current_catcher;
975796c8dcSSimon Schubert   current_catcher = new_catcher;
985796c8dcSSimon Schubert   new_catcher->state = CATCHER_CREATED;
995796c8dcSSimon Schubert 
1005796c8dcSSimon Schubert   return &new_catcher->buf;
1015796c8dcSSimon Schubert }
1025796c8dcSSimon Schubert 
1035796c8dcSSimon Schubert static void
1045796c8dcSSimon Schubert catcher_pop (void)
1055796c8dcSSimon Schubert {
1065796c8dcSSimon Schubert   struct catcher *old_catcher = current_catcher;
107cf7f2e2dSJohn Marino 
1085796c8dcSSimon Schubert   current_catcher = old_catcher->prev;
1095796c8dcSSimon Schubert 
1105796c8dcSSimon Schubert   /* Restore the cleanup chain, the error/quit messages, and the uiout
1115796c8dcSSimon Schubert      builder, to their original states.  */
1125796c8dcSSimon Schubert 
1135796c8dcSSimon Schubert   restore_cleanups (old_catcher->saved_cleanup_chain);
1145796c8dcSSimon Schubert 
1155796c8dcSSimon Schubert   uiout = old_catcher->saved_uiout;
1165796c8dcSSimon Schubert 
1175796c8dcSSimon Schubert   xfree (old_catcher);
1185796c8dcSSimon Schubert }
1195796c8dcSSimon Schubert 
1205796c8dcSSimon Schubert /* Catcher state machine.  Returns non-zero if the m/c should be run
1215796c8dcSSimon Schubert    again, zero if it should abort.  */
1225796c8dcSSimon Schubert 
1235796c8dcSSimon Schubert static int
1245796c8dcSSimon Schubert exceptions_state_mc (enum catcher_action action)
1255796c8dcSSimon Schubert {
1265796c8dcSSimon Schubert   switch (current_catcher->state)
1275796c8dcSSimon Schubert     {
1285796c8dcSSimon Schubert     case CATCHER_CREATED:
1295796c8dcSSimon Schubert       switch (action)
1305796c8dcSSimon Schubert 	{
1315796c8dcSSimon Schubert 	case CATCH_ITER:
1325796c8dcSSimon Schubert 	  /* Allow the code to run the catcher.  */
1335796c8dcSSimon Schubert 	  current_catcher->state = CATCHER_RUNNING;
1345796c8dcSSimon Schubert 	  return 1;
1355796c8dcSSimon Schubert 	default:
1365796c8dcSSimon Schubert 	  internal_error (__FILE__, __LINE__, _("bad state"));
1375796c8dcSSimon Schubert 	}
1385796c8dcSSimon Schubert     case CATCHER_RUNNING:
1395796c8dcSSimon Schubert       switch (action)
1405796c8dcSSimon Schubert 	{
1415796c8dcSSimon Schubert 	case CATCH_ITER:
1425796c8dcSSimon Schubert 	  /* No error/quit has occured.  Just clean up.  */
1435796c8dcSSimon Schubert 	  catcher_pop ();
1445796c8dcSSimon Schubert 	  return 0;
1455796c8dcSSimon Schubert 	case CATCH_ITER_1:
1465796c8dcSSimon Schubert 	  current_catcher->state = CATCHER_RUNNING_1;
1475796c8dcSSimon Schubert 	  return 1;
1485796c8dcSSimon Schubert 	case CATCH_THROWING:
1495796c8dcSSimon Schubert 	  current_catcher->state = CATCHER_ABORTING;
1505796c8dcSSimon Schubert 	  /* See also throw_exception.  */
1515796c8dcSSimon Schubert 	  return 1;
1525796c8dcSSimon Schubert 	default:
1535796c8dcSSimon Schubert 	  internal_error (__FILE__, __LINE__, _("bad switch"));
1545796c8dcSSimon Schubert 	}
1555796c8dcSSimon Schubert     case CATCHER_RUNNING_1:
1565796c8dcSSimon Schubert       switch (action)
1575796c8dcSSimon Schubert 	{
1585796c8dcSSimon Schubert 	case CATCH_ITER:
1595796c8dcSSimon Schubert 	  /* The did a "break" from the inner while loop.  */
1605796c8dcSSimon Schubert 	  catcher_pop ();
1615796c8dcSSimon Schubert 	  return 0;
1625796c8dcSSimon Schubert 	case CATCH_ITER_1:
1635796c8dcSSimon Schubert 	  current_catcher->state = CATCHER_RUNNING;
1645796c8dcSSimon Schubert 	  return 0;
1655796c8dcSSimon Schubert 	case CATCH_THROWING:
1665796c8dcSSimon Schubert 	  current_catcher->state = CATCHER_ABORTING;
1675796c8dcSSimon Schubert 	  /* See also throw_exception.  */
1685796c8dcSSimon Schubert 	  return 1;
1695796c8dcSSimon Schubert 	default:
1705796c8dcSSimon Schubert 	  internal_error (__FILE__, __LINE__, _("bad switch"));
1715796c8dcSSimon Schubert 	}
1725796c8dcSSimon Schubert     case CATCHER_ABORTING:
1735796c8dcSSimon Schubert       switch (action)
1745796c8dcSSimon Schubert 	{
1755796c8dcSSimon Schubert 	case CATCH_ITER:
1765796c8dcSSimon Schubert 	  {
1775796c8dcSSimon Schubert 	    struct gdb_exception exception = *current_catcher->exception;
178cf7f2e2dSJohn Marino 
1795796c8dcSSimon Schubert 	    if (current_catcher->mask & RETURN_MASK (exception.reason))
1805796c8dcSSimon Schubert 	      {
1815796c8dcSSimon Schubert 		/* Exit normally if this catcher can handle this
1825796c8dcSSimon Schubert 		   exception.  The caller analyses the func return
1835796c8dcSSimon Schubert 		   values.  */
1845796c8dcSSimon Schubert 		catcher_pop ();
1855796c8dcSSimon Schubert 		return 0;
1865796c8dcSSimon Schubert 	      }
1875796c8dcSSimon Schubert 	    /* The caller didn't request that the event be caught,
1885796c8dcSSimon Schubert 	       relay the event to the next containing
1895796c8dcSSimon Schubert 	       catch_errors().  */
1905796c8dcSSimon Schubert 	    catcher_pop ();
1915796c8dcSSimon Schubert 	    throw_exception (exception);
1925796c8dcSSimon Schubert 	  }
1935796c8dcSSimon Schubert 	default:
1945796c8dcSSimon Schubert 	  internal_error (__FILE__, __LINE__, _("bad state"));
1955796c8dcSSimon Schubert 	}
1965796c8dcSSimon Schubert     default:
1975796c8dcSSimon Schubert       internal_error (__FILE__, __LINE__, _("bad switch"));
1985796c8dcSSimon Schubert     }
1995796c8dcSSimon Schubert }
2005796c8dcSSimon Schubert 
2015796c8dcSSimon Schubert int
2025796c8dcSSimon Schubert exceptions_state_mc_action_iter (void)
2035796c8dcSSimon Schubert {
2045796c8dcSSimon Schubert   return exceptions_state_mc (CATCH_ITER);
2055796c8dcSSimon Schubert }
2065796c8dcSSimon Schubert 
2075796c8dcSSimon Schubert int
2085796c8dcSSimon Schubert exceptions_state_mc_action_iter_1 (void)
2095796c8dcSSimon Schubert {
2105796c8dcSSimon Schubert   return exceptions_state_mc (CATCH_ITER_1);
2115796c8dcSSimon Schubert }
2125796c8dcSSimon Schubert 
2135796c8dcSSimon Schubert /* Return EXCEPTION to the nearest containing catch_errors().  */
2145796c8dcSSimon Schubert 
215cf7f2e2dSJohn Marino void
2165796c8dcSSimon Schubert throw_exception (struct gdb_exception exception)
2175796c8dcSSimon Schubert {
2185796c8dcSSimon Schubert   struct thread_info *tp = NULL;
2195796c8dcSSimon Schubert 
2205796c8dcSSimon Schubert   quit_flag = 0;
2215796c8dcSSimon Schubert   immediate_quit = 0;
2225796c8dcSSimon Schubert 
2235796c8dcSSimon Schubert   if (!ptid_equal (inferior_ptid, null_ptid))
2245796c8dcSSimon Schubert     tp = find_thread_ptid (inferior_ptid);
2255796c8dcSSimon Schubert 
2265796c8dcSSimon Schubert   /* Perhaps it would be cleaner to do this via the cleanup chain (not sure
2275796c8dcSSimon Schubert      I can think of a reason why that is vital, though).  */
2285796c8dcSSimon Schubert   if (tp != NULL)
229*c50c785cSJohn Marino     {
230*c50c785cSJohn Marino       /* Clear queued breakpoint commands.  */
231*c50c785cSJohn Marino       bpstat_clear_actions (tp->control.stop_bpstat);
232*c50c785cSJohn Marino     }
2335796c8dcSSimon Schubert 
2345796c8dcSSimon Schubert   disable_current_display ();
2355796c8dcSSimon Schubert   do_cleanups (ALL_CLEANUPS);
2365796c8dcSSimon Schubert 
2375796c8dcSSimon Schubert   /* Jump to the containing catch_errors() call, communicating REASON
2385796c8dcSSimon Schubert      to that call via setjmp's return value.  Note that REASON can't
2395796c8dcSSimon Schubert      be zero, by definition in defs.h.  */
2405796c8dcSSimon Schubert   exceptions_state_mc (CATCH_THROWING);
2415796c8dcSSimon Schubert   *current_catcher->exception = exception;
2425796c8dcSSimon Schubert   EXCEPTIONS_SIGLONGJMP (current_catcher->buf, exception.reason);
2435796c8dcSSimon Schubert }
2445796c8dcSSimon Schubert 
2455796c8dcSSimon Schubert static char *last_message;
2465796c8dcSSimon Schubert 
247cf7f2e2dSJohn Marino void
2485796c8dcSSimon Schubert deprecated_throw_reason (enum return_reason reason)
2495796c8dcSSimon Schubert {
2505796c8dcSSimon Schubert   struct gdb_exception exception;
251cf7f2e2dSJohn Marino 
2525796c8dcSSimon Schubert   memset (&exception, 0, sizeof exception);
2535796c8dcSSimon Schubert 
2545796c8dcSSimon Schubert   exception.reason = reason;
2555796c8dcSSimon Schubert   switch (reason)
2565796c8dcSSimon Schubert     {
2575796c8dcSSimon Schubert     case RETURN_QUIT:
2585796c8dcSSimon Schubert       break;
2595796c8dcSSimon Schubert     case RETURN_ERROR:
2605796c8dcSSimon Schubert       exception.error = GENERIC_ERROR;
2615796c8dcSSimon Schubert       break;
2625796c8dcSSimon Schubert     default:
2635796c8dcSSimon Schubert       internal_error (__FILE__, __LINE__, _("bad switch"));
2645796c8dcSSimon Schubert     }
2655796c8dcSSimon Schubert 
2665796c8dcSSimon Schubert   throw_exception (exception);
2675796c8dcSSimon Schubert }
2685796c8dcSSimon Schubert 
2695796c8dcSSimon Schubert static void
2705796c8dcSSimon Schubert print_flush (void)
2715796c8dcSSimon Schubert {
2725796c8dcSSimon Schubert   struct serial *gdb_stdout_serial;
2735796c8dcSSimon Schubert 
2745796c8dcSSimon Schubert   if (deprecated_error_begin_hook)
2755796c8dcSSimon Schubert     deprecated_error_begin_hook ();
2765796c8dcSSimon Schubert   target_terminal_ours ();
2775796c8dcSSimon Schubert 
2785796c8dcSSimon Schubert   /* We want all output to appear now, before we print the error.  We
2795796c8dcSSimon Schubert      have 3 levels of buffering we have to flush (it's possible that
2805796c8dcSSimon Schubert      some of these should be changed to flush the lower-level ones
2815796c8dcSSimon Schubert      too):  */
2825796c8dcSSimon Schubert 
2835796c8dcSSimon Schubert   /* 1.  The _filtered buffer.  */
2845796c8dcSSimon Schubert   wrap_here ("");
2855796c8dcSSimon Schubert 
2865796c8dcSSimon Schubert   /* 2.  The stdio buffer.  */
2875796c8dcSSimon Schubert   gdb_flush (gdb_stdout);
2885796c8dcSSimon Schubert   gdb_flush (gdb_stderr);
2895796c8dcSSimon Schubert 
2905796c8dcSSimon Schubert   /* 3.  The system-level buffer.  */
2915796c8dcSSimon Schubert   gdb_stdout_serial = serial_fdopen (1);
2925796c8dcSSimon Schubert   if (gdb_stdout_serial)
2935796c8dcSSimon Schubert     {
2945796c8dcSSimon Schubert       serial_drain_output (gdb_stdout_serial);
2955796c8dcSSimon Schubert       serial_un_fdopen (gdb_stdout_serial);
2965796c8dcSSimon Schubert     }
2975796c8dcSSimon Schubert 
2985796c8dcSSimon Schubert   annotate_error_begin ();
2995796c8dcSSimon Schubert }
3005796c8dcSSimon Schubert 
3015796c8dcSSimon Schubert static void
3025796c8dcSSimon Schubert print_exception (struct ui_file *file, struct gdb_exception e)
3035796c8dcSSimon Schubert {
3045796c8dcSSimon Schubert   /* KLUGE: cagney/2005-01-13: Write the string out one line at a time
3055796c8dcSSimon Schubert      as that way the MI's behavior is preserved.  */
3065796c8dcSSimon Schubert   const char *start;
3075796c8dcSSimon Schubert   const char *end;
308cf7f2e2dSJohn Marino 
3095796c8dcSSimon Schubert   for (start = e.message; start != NULL; start = end)
3105796c8dcSSimon Schubert     {
3115796c8dcSSimon Schubert       end = strchr (start, '\n');
3125796c8dcSSimon Schubert       if (end == NULL)
3135796c8dcSSimon Schubert 	fputs_filtered (start, file);
3145796c8dcSSimon Schubert       else
3155796c8dcSSimon Schubert 	{
3165796c8dcSSimon Schubert 	  end++;
3175796c8dcSSimon Schubert 	  ui_file_write (file, start, end - start);
3185796c8dcSSimon Schubert 	}
3195796c8dcSSimon Schubert     }
3205796c8dcSSimon Schubert   fprintf_filtered (file, "\n");
3215796c8dcSSimon Schubert 
3225796c8dcSSimon Schubert   /* Now append the annotation.  */
3235796c8dcSSimon Schubert   switch (e.reason)
3245796c8dcSSimon Schubert     {
3255796c8dcSSimon Schubert     case RETURN_QUIT:
3265796c8dcSSimon Schubert       annotate_quit ();
3275796c8dcSSimon Schubert       break;
3285796c8dcSSimon Schubert     case RETURN_ERROR:
3295796c8dcSSimon Schubert       /* Assume that these are all errors.  */
3305796c8dcSSimon Schubert       annotate_error ();
3315796c8dcSSimon Schubert       break;
3325796c8dcSSimon Schubert     default:
3335796c8dcSSimon Schubert       internal_error (__FILE__, __LINE__, _("Bad switch."));
3345796c8dcSSimon Schubert     }
3355796c8dcSSimon Schubert }
3365796c8dcSSimon Schubert 
3375796c8dcSSimon Schubert void
3385796c8dcSSimon Schubert exception_print (struct ui_file *file, struct gdb_exception e)
3395796c8dcSSimon Schubert {
3405796c8dcSSimon Schubert   if (e.reason < 0 && e.message != NULL)
3415796c8dcSSimon Schubert     {
3425796c8dcSSimon Schubert       print_flush ();
3435796c8dcSSimon Schubert       print_exception (file, e);
3445796c8dcSSimon Schubert     }
3455796c8dcSSimon Schubert }
3465796c8dcSSimon Schubert 
3475796c8dcSSimon Schubert void
3485796c8dcSSimon Schubert exception_fprintf (struct ui_file *file, struct gdb_exception e,
3495796c8dcSSimon Schubert 		   const char *prefix, ...)
3505796c8dcSSimon Schubert {
3515796c8dcSSimon Schubert   if (e.reason < 0 && e.message != NULL)
3525796c8dcSSimon Schubert     {
3535796c8dcSSimon Schubert       va_list args;
3545796c8dcSSimon Schubert 
3555796c8dcSSimon Schubert       print_flush ();
3565796c8dcSSimon Schubert 
3575796c8dcSSimon Schubert       /* Print the prefix.  */
3585796c8dcSSimon Schubert       va_start (args, prefix);
3595796c8dcSSimon Schubert       vfprintf_filtered (file, prefix, args);
3605796c8dcSSimon Schubert       va_end (args);
3615796c8dcSSimon Schubert 
3625796c8dcSSimon Schubert       print_exception (file, e);
3635796c8dcSSimon Schubert     }
3645796c8dcSSimon Schubert }
3655796c8dcSSimon Schubert 
3665796c8dcSSimon Schubert static void
3675796c8dcSSimon Schubert print_any_exception (struct ui_file *file, const char *prefix,
3685796c8dcSSimon Schubert 		     struct gdb_exception e)
3695796c8dcSSimon Schubert {
3705796c8dcSSimon Schubert   if (e.reason < 0 && e.message != NULL)
3715796c8dcSSimon Schubert     {
3725796c8dcSSimon Schubert       target_terminal_ours ();
373*c50c785cSJohn Marino       wrap_here ("");		/* Force out any buffered output.  */
3745796c8dcSSimon Schubert       gdb_flush (gdb_stdout);
3755796c8dcSSimon Schubert       annotate_error_begin ();
3765796c8dcSSimon Schubert 
3775796c8dcSSimon Schubert       /* Print the prefix.  */
3785796c8dcSSimon Schubert       if (prefix != NULL && prefix[0] != '\0')
3795796c8dcSSimon Schubert 	fputs_filtered (prefix, file);
3805796c8dcSSimon Schubert       print_exception (file, e);
3815796c8dcSSimon Schubert     }
3825796c8dcSSimon Schubert }
3835796c8dcSSimon Schubert 
384cf7f2e2dSJohn Marino static void ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 0)
3855796c8dcSSimon Schubert throw_it (enum return_reason reason, enum errors error, const char *fmt,
3865796c8dcSSimon Schubert 	  va_list ap)
3875796c8dcSSimon Schubert {
3885796c8dcSSimon Schubert   struct gdb_exception e;
3895796c8dcSSimon Schubert   char *new_message;
3905796c8dcSSimon Schubert 
3915796c8dcSSimon Schubert   /* Save the message.  Create the new message before deleting the
3925796c8dcSSimon Schubert      old, the new message may include the old message text.  */
3935796c8dcSSimon Schubert   new_message = xstrvprintf (fmt, ap);
3945796c8dcSSimon Schubert   xfree (last_message);
3955796c8dcSSimon Schubert   last_message = new_message;
3965796c8dcSSimon Schubert 
3975796c8dcSSimon Schubert   /* Create the exception.  */
3985796c8dcSSimon Schubert   e.reason = reason;
3995796c8dcSSimon Schubert   e.error = error;
4005796c8dcSSimon Schubert   e.message = last_message;
4015796c8dcSSimon Schubert 
4025796c8dcSSimon Schubert   /* Throw the exception.  */
4035796c8dcSSimon Schubert   throw_exception (e);
4045796c8dcSSimon Schubert }
4055796c8dcSSimon Schubert 
406cf7f2e2dSJohn Marino void
4075796c8dcSSimon Schubert throw_verror (enum errors error, const char *fmt, va_list ap)
4085796c8dcSSimon Schubert {
4095796c8dcSSimon Schubert   throw_it (RETURN_ERROR, error, fmt, ap);
4105796c8dcSSimon Schubert }
4115796c8dcSSimon Schubert 
412cf7f2e2dSJohn Marino void
4135796c8dcSSimon Schubert throw_vfatal (const char *fmt, va_list ap)
4145796c8dcSSimon Schubert {
4155796c8dcSSimon Schubert   throw_it (RETURN_QUIT, GDB_NO_ERROR, fmt, ap);
4165796c8dcSSimon Schubert }
4175796c8dcSSimon Schubert 
418cf7f2e2dSJohn Marino void
4195796c8dcSSimon Schubert throw_error (enum errors error, const char *fmt, ...)
4205796c8dcSSimon Schubert {
4215796c8dcSSimon Schubert   va_list args;
422cf7f2e2dSJohn Marino 
4235796c8dcSSimon Schubert   va_start (args, fmt);
4245796c8dcSSimon Schubert   throw_it (RETURN_ERROR, error, fmt, args);
4255796c8dcSSimon Schubert   va_end (args);
4265796c8dcSSimon Schubert }
4275796c8dcSSimon Schubert 
4285796c8dcSSimon Schubert /* Call FUNC(UIOUT, FUNC_ARGS) but wrapped within an exception
4295796c8dcSSimon Schubert    handler.  If an exception (enum return_reason) is thrown using
4305796c8dcSSimon Schubert    throw_exception() than all cleanups installed since
4315796c8dcSSimon Schubert    catch_exceptions() was entered are invoked, the (-ve) exception
4325796c8dcSSimon Schubert    value is then returned by catch_exceptions.  If FUNC() returns
4335796c8dcSSimon Schubert    normally (with a positive or zero return value) then that value is
4345796c8dcSSimon Schubert    returned by catch_exceptions().  It is an internal_error() for
4355796c8dcSSimon Schubert    FUNC() to return a negative value.
4365796c8dcSSimon Schubert 
4375796c8dcSSimon Schubert    See exceptions.h for further usage details.
4385796c8dcSSimon Schubert 
4395796c8dcSSimon Schubert    Must not be called with immediate_quit in effect (bad things might
4405796c8dcSSimon Schubert    happen, say we got a signal in the middle of a memcpy to quit_return).
4415796c8dcSSimon Schubert    This is an OK restriction; with very few exceptions immediate_quit can
4425796c8dcSSimon Schubert    be replaced by judicious use of QUIT.  */
4435796c8dcSSimon Schubert 
4445796c8dcSSimon Schubert /* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with
445*c50c785cSJohn Marino    error() et al. could maintain a set of flags that indicate the the
4465796c8dcSSimon Schubert    current state of each of the longjmp buffers.  This would give the
4475796c8dcSSimon Schubert    longjmp code the chance to detect a longjmp botch (before it gets
4485796c8dcSSimon Schubert    to longjmperror()).  Prior to 1999-11-05 this wasn't possible as
4495796c8dcSSimon Schubert    code also randomly used a SET_TOP_LEVEL macro that directly
450*c50c785cSJohn Marino    initialized the longjmp buffers.  */
4515796c8dcSSimon Schubert 
4525796c8dcSSimon Schubert int
4535796c8dcSSimon Schubert catch_exceptions (struct ui_out *uiout,
4545796c8dcSSimon Schubert 		  catch_exceptions_ftype *func,
4555796c8dcSSimon Schubert 		  void *func_args,
4565796c8dcSSimon Schubert 		  return_mask mask)
4575796c8dcSSimon Schubert {
4585796c8dcSSimon Schubert   return catch_exceptions_with_msg (uiout, func, func_args, NULL, mask);
4595796c8dcSSimon Schubert }
4605796c8dcSSimon Schubert 
4615796c8dcSSimon Schubert struct gdb_exception
4625796c8dcSSimon Schubert catch_exception (struct ui_out *uiout,
4635796c8dcSSimon Schubert 		 catch_exception_ftype *func,
4645796c8dcSSimon Schubert 		 void *func_args,
4655796c8dcSSimon Schubert 		 return_mask mask)
4665796c8dcSSimon Schubert {
4675796c8dcSSimon Schubert   volatile struct gdb_exception exception;
468cf7f2e2dSJohn Marino 
4695796c8dcSSimon Schubert   TRY_CATCH (exception, mask)
4705796c8dcSSimon Schubert     {
4715796c8dcSSimon Schubert       (*func) (uiout, func_args);
4725796c8dcSSimon Schubert     }
4735796c8dcSSimon Schubert   return exception;
4745796c8dcSSimon Schubert }
4755796c8dcSSimon Schubert 
4765796c8dcSSimon Schubert int
4775796c8dcSSimon Schubert catch_exceptions_with_msg (struct ui_out *uiout,
4785796c8dcSSimon Schubert 		  	   catch_exceptions_ftype *func,
4795796c8dcSSimon Schubert 		  	   void *func_args,
4805796c8dcSSimon Schubert 			   char **gdberrmsg,
4815796c8dcSSimon Schubert 		  	   return_mask mask)
4825796c8dcSSimon Schubert {
4835796c8dcSSimon Schubert   volatile struct gdb_exception exception;
4845796c8dcSSimon Schubert   volatile int val = 0;
485cf7f2e2dSJohn Marino 
4865796c8dcSSimon Schubert   TRY_CATCH (exception, mask)
4875796c8dcSSimon Schubert     {
4885796c8dcSSimon Schubert       val = (*func) (uiout, func_args);
4895796c8dcSSimon Schubert     }
4905796c8dcSSimon Schubert   print_any_exception (gdb_stderr, NULL, exception);
4915796c8dcSSimon Schubert   gdb_assert (val >= 0);
4925796c8dcSSimon Schubert   gdb_assert (exception.reason <= 0);
4935796c8dcSSimon Schubert   if (exception.reason < 0)
4945796c8dcSSimon Schubert     {
4955796c8dcSSimon Schubert       /* If caller wants a copy of the low-level error message, make
4965796c8dcSSimon Schubert 	 one.  This is used in the case of a silent error whereby the
4975796c8dcSSimon Schubert 	 caller may optionally want to issue the message.  */
4985796c8dcSSimon Schubert       if (gdberrmsg != NULL)
4995796c8dcSSimon Schubert 	{
5005796c8dcSSimon Schubert 	  if (exception.message != NULL)
5015796c8dcSSimon Schubert 	    *gdberrmsg = xstrdup (exception.message);
5025796c8dcSSimon Schubert 	  else
5035796c8dcSSimon Schubert 	    *gdberrmsg = NULL;
5045796c8dcSSimon Schubert 	}
5055796c8dcSSimon Schubert       return exception.reason;
5065796c8dcSSimon Schubert     }
5075796c8dcSSimon Schubert   return val;
5085796c8dcSSimon Schubert }
5095796c8dcSSimon Schubert 
5105796c8dcSSimon Schubert /* This function is superseded by catch_exceptions().  */
5115796c8dcSSimon Schubert 
5125796c8dcSSimon Schubert int
5135796c8dcSSimon Schubert catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
5145796c8dcSSimon Schubert 	      return_mask mask)
5155796c8dcSSimon Schubert {
5165796c8dcSSimon Schubert   volatile int val = 0;
5175796c8dcSSimon Schubert   volatile struct gdb_exception exception;
518cf7f2e2dSJohn Marino 
5195796c8dcSSimon Schubert   TRY_CATCH (exception, mask)
5205796c8dcSSimon Schubert     {
5215796c8dcSSimon Schubert       val = func (func_args);
5225796c8dcSSimon Schubert     }
5235796c8dcSSimon Schubert   print_any_exception (gdb_stderr, errstring, exception);
5245796c8dcSSimon Schubert   if (exception.reason != 0)
5255796c8dcSSimon Schubert     return 0;
5265796c8dcSSimon Schubert   return val;
5275796c8dcSSimon Schubert }
5285796c8dcSSimon Schubert 
5295796c8dcSSimon Schubert int
5305796c8dcSSimon Schubert catch_command_errors (catch_command_errors_ftype * command,
5315796c8dcSSimon Schubert 		      char *arg, int from_tty, return_mask mask)
5325796c8dcSSimon Schubert {
5335796c8dcSSimon Schubert   volatile struct gdb_exception e;
534cf7f2e2dSJohn Marino 
5355796c8dcSSimon Schubert   TRY_CATCH (e, mask)
5365796c8dcSSimon Schubert     {
5375796c8dcSSimon Schubert       command (arg, from_tty);
5385796c8dcSSimon Schubert     }
5395796c8dcSSimon Schubert   print_any_exception (gdb_stderr, NULL, e);
5405796c8dcSSimon Schubert   if (e.reason < 0)
5415796c8dcSSimon Schubert     return 0;
5425796c8dcSSimon Schubert   return 1;
5435796c8dcSSimon Schubert }
544