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