binutils-gdb/gdb/exceptions.c
Gary Benson 6d3d12ebef Include string.h in common-defs.h
This commit includes string.h in common-defs.h and removes all other
inclusions.

gdb/
2014-08-07  Gary Benson  <gbenson@redhat.com>

	* common/common-defs.h: Include string.h.
	* aarch64-tdep.c: Do not include string.h.
	* ada-exp.y: Likewise.
	* ada-lang.c: Likewise.
	* ada-lex.l: Likewise.
	* ada-typeprint.c: Likewise.
	* ada-valprint.c: Likewise.
	* aix-thread.c: Likewise.
	* alpha-linux-tdep.c: Likewise.
	* alpha-mdebug-tdep.c: Likewise.
	* alpha-nat.c: Likewise.
	* alpha-osf1-tdep.c: Likewise.
	* alpha-tdep.c: Likewise.
	* alphanbsd-tdep.c: Likewise.
	* amd64-dicos-tdep.c: Likewise.
	* amd64-linux-tdep.c: Likewise.
	* amd64-nat.c: Likewise.
	* amd64-sol2-tdep.c: Likewise.
	* amd64fbsd-tdep.c: Likewise.
	* amd64obsd-tdep.c: Likewise.
	* arch-utils.c: Likewise.
	* arm-linux-nat.c: Likewise.
	* arm-linux-tdep.c: Likewise.
	* arm-tdep.c: Likewise.
	* arm-wince-tdep.c: Likewise.
	* armbsd-tdep.c: Likewise.
	* armnbsd-nat.c: Likewise.
	* armnbsd-tdep.c: Likewise.
	* armobsd-tdep.c: Likewise.
	* avr-tdep.c: Likewise.
	* ax-gdb.c: Likewise.
	* ax-general.c: Likewise.
	* bcache.c: Likewise.
	* bfin-tdep.c: Likewise.
	* breakpoint.c: Likewise.
	* build-id.c: Likewise.
	* buildsym.c: Likewise.
	* c-exp.y: Likewise.
	* c-lang.c: Likewise.
	* c-typeprint.c: Likewise.
	* c-valprint.c: Likewise.
	* charset.c: Likewise.
	* cli-out.c: Likewise.
	* cli/cli-cmds.c: Likewise.
	* cli/cli-decode.c: Likewise.
	* cli/cli-dump.c: Likewise.
	* cli/cli-interp.c: Likewise.
	* cli/cli-logging.c: Likewise.
	* cli/cli-script.c: Likewise.
	* cli/cli-setshow.c: Likewise.
	* cli/cli-utils.c: Likewise.
	* coffread.c: Likewise.
	* common/agent.c: Likewise.
	* common/buffer.c: Likewise.
	* common/buffer.h: Likewise.
	* common/common-utils.c: Likewise.
	* common/filestuff.c: Likewise.
	* common/filestuff.c: Likewise.
	* common/format.c: Likewise.
	* common/print-utils.c: Likewise.
	* common/rsp-low.c: Likewise.
	* common/signals.c: Likewise.
	* common/vec.h: Likewise.
	* common/xml-utils.c: Likewise.
	* core-regset.c: Likewise.
	* corefile.c: Likewise.
	* corelow.c: Likewise.
	* cp-abi.c: Likewise.
	* cp-name-parser.y: Likewise.
	* cp-support.c: Likewise.
	* cp-valprint.c: Likewise.
	* cris-tdep.c: Likewise.
	* d-exp.y: Likewise.
	* darwin-nat.c: Likewise.
	* dbxread.c: Likewise.
	* dcache.c: Likewise.
	* demangle.c: Likewise.
	* dicos-tdep.c: Likewise.
	* disasm.c: Likewise.
	* doublest.c: Likewise.
	* dsrec.c: Likewise.
	* dummy-frame.c: Likewise.
	* dwarf2-frame.c: Likewise.
	* dwarf2loc.c: Likewise.
	* dwarf2read.c: Likewise.
	* elfread.c: Likewise.
	* environ.c: Likewise.
	* eval.c: Likewise.
	* event-loop.c: Likewise.
	* exceptions.c: Likewise.
	* exec.c: Likewise.
	* expprint.c: Likewise.
	* f-exp.y: Likewise.
	* f-lang.c: Likewise.
	* f-typeprint.c: Likewise.
	* f-valprint.c: Likewise.
	* fbsd-nat.c: Likewise.
	* findcmd.c: Likewise.
	* findvar.c: Likewise.
	* fork-child.c: Likewise.
	* frame.c: Likewise.
	* frv-linux-tdep.c: Likewise.
	* frv-tdep.c: Likewise.
	* gdb.c: Likewise.
	* gdb_bfd.c: Likewise.
	* gdbarch.c: Likewise.
	* gdbarch.sh: Likewise.
	* gdbtypes.c: Likewise.
	* gnu-nat.c: Likewise.
	* gnu-v2-abi.c: Likewise.
	* gnu-v3-abi.c: Likewise.
	* go-exp.y: Likewise.
	* go-lang.c: Likewise.
	* go32-nat.c: Likewise.
	* guile/guile.c: Likewise.
	* guile/scm-auto-load.c: Likewise.
	* hppa-hpux-tdep.c: Likewise.
	* hppa-linux-nat.c: Likewise.
	* hppanbsd-tdep.c: Likewise.
	* hppaobsd-tdep.c: Likewise.
	* i386-cygwin-tdep.c: Likewise.
	* i386-dicos-tdep.c: Likewise.
	* i386-linux-tdep.c: Likewise.
	* i386-nto-tdep.c: Likewise.
	* i386-sol2-tdep.c: Likewise.
	* i386-tdep.c: Likewise.
	* i386bsd-tdep.c: Likewise.
	* i386gnu-nat.c: Likewise.
	* i386nbsd-tdep.c: Likewise.
	* i386obsd-tdep.c: Likewise.
	* i387-tdep.c: Likewise.
	* ia64-libunwind-tdep.c: Likewise.
	* ia64-linux-nat.c: Likewise.
	* inf-child.c: Likewise.
	* inf-ptrace.c: Likewise.
	* inf-ttrace.c: Likewise.
	* infcall.c: Likewise.
	* infcmd.c: Likewise.
	* inflow.c: Likewise.
	* infrun.c: Likewise.
	* interps.c: Likewise.
	* iq2000-tdep.c: Likewise.
	* irix5-nat.c: Likewise.
	* jv-exp.y: Likewise.
	* jv-lang.c: Likewise.
	* jv-typeprint.c: Likewise.
	* jv-valprint.c: Likewise.
	* language.c: Likewise.
	* linux-fork.c: Likewise.
	* linux-nat.c: Likewise.
	* lm32-tdep.c: Likewise.
	* m2-exp.y: Likewise.
	* m2-typeprint.c: Likewise.
	* m32c-tdep.c: Likewise.
	* m32r-linux-nat.c: Likewise.
	* m32r-linux-tdep.c: Likewise.
	* m32r-rom.c: Likewise.
	* m32r-tdep.c: Likewise.
	* m68hc11-tdep.c: Likewise.
	* m68k-tdep.c: Likewise.
	* m68kbsd-tdep.c: Likewise.
	* m68klinux-nat.c: Likewise.
	* m68klinux-tdep.c: Likewise.
	* m88k-tdep.c: Likewise.
	* machoread.c: Likewise.
	* macrocmd.c: Likewise.
	* main.c: Likewise.
	* mdebugread.c: Likewise.
	* mem-break.c: Likewise.
	* memattr.c: Likewise.
	* memory-map.c: Likewise.
	* mep-tdep.c: Likewise.
	* mi/mi-cmd-break.c: Likewise.
	* mi/mi-cmd-disas.c: Likewise.
	* mi/mi-cmd-env.c: Likewise.
	* mi/mi-cmd-stack.c: Likewise.
	* mi/mi-cmd-var.c: Likewise.
	* mi/mi-cmds.c: Likewise.
	* mi/mi-console.c: Likewise.
	* mi/mi-getopt.c: Likewise.
	* mi/mi-interp.c: Likewise.
	* mi/mi-main.c: Likewise.
	* mi/mi-parse.c: Likewise.
	* microblaze-rom.c: Likewise.
	* microblaze-tdep.c: Likewise.
	* mingw-hdep.c: Likewise.
	* minidebug.c: Likewise.
	* minsyms.c: Likewise.
	* mips-irix-tdep.c: Likewise.
	* mips-linux-tdep.c: Likewise.
	* mips-tdep.c: Likewise.
	* mips64obsd-tdep.c: Likewise.
	* mipsnbsd-tdep.c: Likewise.
	* mipsread.c: Likewise.
	* mn10300-linux-tdep.c: Likewise.
	* mn10300-tdep.c: Likewise.
	* monitor.c: Likewise.
	* moxie-tdep.c: Likewise.
	* mt-tdep.c: Likewise.
	* nat/linux-btrace.c: Likewise.
	* nat/linux-osdata.c: Likewise.
	* nat/linux-procfs.c: Likewise.
	* nat/linux-ptrace.c: Likewise.
	* nat/linux-waitpid.c: Likewise.
	* nbsd-tdep.c: Likewise.
	* nios2-linux-tdep.c: Likewise.
	* nto-procfs.c: Likewise.
	* nto-tdep.c: Likewise.
	* objc-lang.c: Likewise.
	* objfiles.c: Likewise.
	* opencl-lang.c: Likewise.
	* osabi.c: Likewise.
	* osdata.c: Likewise.
	* p-exp.y: Likewise.
	* p-lang.c: Likewise.
	* p-typeprint.c: Likewise.
	* parse.c: Likewise.
	* posix-hdep.c: Likewise.
	* ppc-linux-nat.c: Likewise.
	* ppc-sysv-tdep.c: Likewise.
	* ppcfbsd-tdep.c: Likewise.
	* ppcnbsd-tdep.c: Likewise.
	* ppcobsd-tdep.c: Likewise.
	* printcmd.c: Likewise.
	* procfs.c: Likewise.
	* prologue-value.c: Likewise.
	* python/py-auto-load.c: Likewise.
	* python/py-gdb-readline.c: Likewise.
	* ravenscar-thread.c: Likewise.
	* regcache.c: Likewise.
	* registry.c: Likewise.
	* remote-fileio.c: Likewise.
	* remote-m32r-sdi.c: Likewise.
	* remote-mips.c: Likewise.
	* remote-notif.c: Likewise.
	* remote-sim.c: Likewise.
	* remote.c: Likewise.
	* reverse.c: Likewise.
	* rs6000-aix-tdep.c: Likewise.
	* ser-base.c: Likewise.
	* ser-go32.c: Likewise.
	* ser-mingw.c: Likewise.
	* ser-pipe.c: Likewise.
	* ser-tcp.c: Likewise.
	* ser-unix.c: Likewise.
	* serial.c: Likewise.
	* sh-tdep.c: Likewise.
	* sh64-tdep.c: Likewise.
	* shnbsd-tdep.c: Likewise.
	* skip.c: Likewise.
	* sol-thread.c: Likewise.
	* solib-dsbt.c: Likewise.
	* solib-frv.c: Likewise.
	* solib-osf.c: Likewise.
	* solib-som.c: Likewise.
	* solib-spu.c: Likewise.
	* solib-target.c: Likewise.
	* solib.c: Likewise.
	* somread.c: Likewise.
	* source.c: Likewise.
	* sparc-nat.c: Likewise.
	* sparc-sol2-tdep.c: Likewise.
	* sparc-tdep.c: Likewise.
	* sparc64-tdep.c: Likewise.
	* sparc64fbsd-tdep.c: Likewise.
	* sparc64nbsd-tdep.c: Likewise.
	* sparcnbsd-tdep.c: Likewise.
	* spu-linux-nat.c: Likewise.
	* spu-multiarch.c: Likewise.
	* spu-tdep.c: Likewise.
	* stabsread.c: Likewise.
	* stack.c: Likewise.
	* std-regs.c: Likewise.
	* symfile.c: Likewise.
	* symmisc.c: Likewise.
	* symtab.c: Likewise.
	* target.c: Likewise.
	* thread.c: Likewise.
	* tilegx-linux-nat.c: Likewise.
	* tilegx-tdep.c: Likewise.
	* top.c: Likewise.
	* tracepoint.c: Likewise.
	* tui/tui-command.c: Likewise.
	* tui/tui-data.c: Likewise.
	* tui/tui-disasm.c: Likewise.
	* tui/tui-file.c: Likewise.
	* tui/tui-layout.c: Likewise.
	* tui/tui-out.c: Likewise.
	* tui/tui-regs.c: Likewise.
	* tui/tui-source.c: Likewise.
	* tui/tui-stack.c: Likewise.
	* tui/tui-win.c: Likewise.
	* tui/tui-windata.c: Likewise.
	* tui/tui-winsource.c: Likewise.
	* typeprint.c: Likewise.
	* ui-file.c: Likewise.
	* ui-out.c: Likewise.
	* user-regs.c: Likewise.
	* utils.c: Likewise.
	* v850-tdep.c: Likewise.
	* valarith.c: Likewise.
	* valops.c: Likewise.
	* valprint.c: Likewise.
	* value.c: Likewise.
	* varobj.c: Likewise.
	* vax-tdep.c: Likewise.
	* vaxnbsd-tdep.c: Likewise.
	* vaxobsd-tdep.c: Likewise.
	* windows-nat.c: Likewise.
	* xcoffread.c: Likewise.
	* xml-support.c: Likewise.
	* xstormy16-tdep.c: Likewise.
	* xtensa-linux-nat.c: Likewise.

gdb/gdbserver/
2014-08-07  Gary Benson  <gbenson@redhat.com>

	* server.h: Do not include string.h.
	* event-loop.c: Likewise.
	* linux-low.c: Likewise.
	* regcache.c: Likewise.
	* remote-utils.c: Likewise.
	* spu-low.c: Likewise.
	* utils.c: Likewise.
2014-08-07 09:06:47 +01:00

532 lines
14 KiB
C

/* Exception (throw catch) mechanism, for GDB, the GNU debugger.
Copyright (C) 1986-2014 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include "exceptions.h"
#include "breakpoint.h"
#include "target.h"
#include "inferior.h"
#include "annotate.h"
#include "ui-out.h"
#include "serial.h"
#include "gdbthread.h"
const struct gdb_exception exception_none = { 0, GDB_NO_ERROR, NULL };
/* Possible catcher states. */
enum catcher_state {
/* Initial state, a new catcher has just been created. */
CATCHER_CREATED,
/* The catch code is running. */
CATCHER_RUNNING,
CATCHER_RUNNING_1,
/* The catch code threw an exception. */
CATCHER_ABORTING
};
/* Possible catcher actions. */
enum catcher_action {
CATCH_ITER,
CATCH_ITER_1,
CATCH_THROWING
};
struct catcher
{
enum catcher_state state;
/* Jump buffer pointing back at the exception handler. */
EXCEPTIONS_SIGJMP_BUF buf;
/* Status buffer belonging to the exception handler. */
volatile struct gdb_exception *exception;
/* Saved/current state. */
int mask;
struct cleanup *saved_cleanup_chain;
/* Back link. */
struct catcher *prev;
};
/* Where to go for throw_exception(). */
static struct catcher *current_catcher;
/* Return length of current_catcher list. */
static int
catcher_list_size (void)
{
int size;
struct catcher *catcher;
for (size = 0, catcher = current_catcher;
catcher != NULL;
catcher = catcher->prev)
++size;
return size;
}
EXCEPTIONS_SIGJMP_BUF *
exceptions_state_mc_init (volatile struct gdb_exception *exception,
return_mask mask)
{
struct catcher *new_catcher = XCNEW (struct catcher);
/* Start with no exception, save it's address. */
exception->reason = 0;
exception->error = GDB_NO_ERROR;
exception->message = NULL;
new_catcher->exception = exception;
new_catcher->mask = mask;
/* Prevent error/quit during FUNC from calling cleanups established
prior to here. */
new_catcher->saved_cleanup_chain = save_cleanups ();
/* Push this new catcher on the top. */
new_catcher->prev = current_catcher;
current_catcher = new_catcher;
new_catcher->state = CATCHER_CREATED;
return &new_catcher->buf;
}
static void
catcher_pop (void)
{
struct catcher *old_catcher = current_catcher;
current_catcher = old_catcher->prev;
/* Restore the cleanup chain, the error/quit messages, and the uiout
builder, to their original states. */
restore_cleanups (old_catcher->saved_cleanup_chain);
xfree (old_catcher);
}
/* Catcher state machine. Returns non-zero if the m/c should be run
again, zero if it should abort. */
static int
exceptions_state_mc (enum catcher_action action)
{
switch (current_catcher->state)
{
case CATCHER_CREATED:
switch (action)
{
case CATCH_ITER:
/* Allow the code to run the catcher. */
current_catcher->state = CATCHER_RUNNING;
return 1;
default:
internal_error (__FILE__, __LINE__, _("bad state"));
}
case CATCHER_RUNNING:
switch (action)
{
case CATCH_ITER:
/* No error/quit has occured. Just clean up. */
catcher_pop ();
return 0;
case CATCH_ITER_1:
current_catcher->state = CATCHER_RUNNING_1;
return 1;
case CATCH_THROWING:
current_catcher->state = CATCHER_ABORTING;
/* See also throw_exception. */
return 1;
default:
internal_error (__FILE__, __LINE__, _("bad switch"));
}
case CATCHER_RUNNING_1:
switch (action)
{
case CATCH_ITER:
/* The did a "break" from the inner while loop. */
catcher_pop ();
return 0;
case CATCH_ITER_1:
current_catcher->state = CATCHER_RUNNING;
return 0;
case CATCH_THROWING:
current_catcher->state = CATCHER_ABORTING;
/* See also throw_exception. */
return 1;
default:
internal_error (__FILE__, __LINE__, _("bad switch"));
}
case CATCHER_ABORTING:
switch (action)
{
case CATCH_ITER:
{
struct gdb_exception exception = *current_catcher->exception;
if (current_catcher->mask & RETURN_MASK (exception.reason))
{
/* Exit normally if this catcher can handle this
exception. The caller analyses the func return
values. */
catcher_pop ();
return 0;
}
/* The caller didn't request that the event be caught,
relay the event to the next containing
catch_errors(). */
catcher_pop ();
throw_exception (exception);
}
default:
internal_error (__FILE__, __LINE__, _("bad state"));
}
default:
internal_error (__FILE__, __LINE__, _("bad switch"));
}
}
int
exceptions_state_mc_action_iter (void)
{
return exceptions_state_mc (CATCH_ITER);
}
int
exceptions_state_mc_action_iter_1 (void)
{
return exceptions_state_mc (CATCH_ITER_1);
}
/* Return EXCEPTION to the nearest containing catch_errors(). */
void
throw_exception (struct gdb_exception exception)
{
clear_quit_flag ();
immediate_quit = 0;
do_cleanups (all_cleanups ());
/* Jump to the containing catch_errors() call, communicating REASON
to that call via setjmp's return value. Note that REASON can't
be zero, by definition in defs.h. */
exceptions_state_mc (CATCH_THROWING);
*current_catcher->exception = exception;
EXCEPTIONS_SIGLONGJMP (current_catcher->buf, exception.reason);
}
static void
print_flush (void)
{
struct serial *gdb_stdout_serial;
if (deprecated_error_begin_hook)
deprecated_error_begin_hook ();
target_terminal_ours ();
/* We want all output to appear now, before we print the error. We
have 3 levels of buffering we have to flush (it's possible that
some of these should be changed to flush the lower-level ones
too): */
/* 1. The _filtered buffer. */
wrap_here ("");
/* 2. The stdio buffer. */
gdb_flush (gdb_stdout);
gdb_flush (gdb_stderr);
/* 3. The system-level buffer. */
gdb_stdout_serial = serial_fdopen (1);
if (gdb_stdout_serial)
{
serial_drain_output (gdb_stdout_serial);
serial_un_fdopen (gdb_stdout_serial);
}
annotate_error_begin ();
}
static void
print_exception (struct ui_file *file, struct gdb_exception e)
{
/* KLUGE: cagney/2005-01-13: Write the string out one line at a time
as that way the MI's behavior is preserved. */
const char *start;
const char *end;
for (start = e.message; start != NULL; start = end)
{
end = strchr (start, '\n');
if (end == NULL)
fputs_filtered (start, file);
else
{
end++;
ui_file_write (file, start, end - start);
}
}
fprintf_filtered (file, "\n");
/* Now append the annotation. */
switch (e.reason)
{
case RETURN_QUIT:
annotate_quit ();
break;
case RETURN_ERROR:
/* Assume that these are all errors. */
annotate_error ();
break;
default:
internal_error (__FILE__, __LINE__, _("Bad switch."));
}
}
void
exception_print (struct ui_file *file, struct gdb_exception e)
{
if (e.reason < 0 && e.message != NULL)
{
print_flush ();
print_exception (file, e);
}
}
void
exception_fprintf (struct ui_file *file, struct gdb_exception e,
const char *prefix, ...)
{
if (e.reason < 0 && e.message != NULL)
{
va_list args;
print_flush ();
/* Print the prefix. */
va_start (args, prefix);
vfprintf_filtered (file, prefix, args);
va_end (args);
print_exception (file, e);
}
}
/* A stack of exception messages.
This is needed to handle nested calls to throw_it: we don't want to
xfree space for a message before it's used.
This can happen if we throw an exception during a cleanup:
An outer TRY_CATCH may have an exception message it wants to print,
but while doing cleanups further calls to throw_it are made.
This is indexed by the size of the current_catcher list.
It is a dynamically allocated array so that we don't care how deeply
GDB nests its TRY_CATCHs. */
static char **exception_messages;
/* The number of currently allocated entries in exception_messages. */
static int exception_messages_size;
static void ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (3, 0)
throw_it (enum return_reason reason, enum errors error, const char *fmt,
va_list ap)
{
struct gdb_exception e;
char *new_message;
int depth = catcher_list_size ();
gdb_assert (depth > 0);
/* Note: The new message may use an old message's text. */
new_message = xstrvprintf (fmt, ap);
if (depth > exception_messages_size)
{
int old_size = exception_messages_size;
exception_messages_size = depth + 10;
exception_messages = (char **) xrealloc (exception_messages,
exception_messages_size
* sizeof (char *));
memset (exception_messages + old_size, 0,
(exception_messages_size - old_size) * sizeof (char *));
}
xfree (exception_messages[depth - 1]);
exception_messages[depth - 1] = new_message;
/* Create the exception. */
e.reason = reason;
e.error = error;
e.message = new_message;
/* Throw the exception. */
throw_exception (e);
}
void
throw_verror (enum errors error, const char *fmt, va_list ap)
{
throw_it (RETURN_ERROR, error, fmt, ap);
}
void
throw_vquit (const char *fmt, va_list ap)
{
throw_it (RETURN_QUIT, GDB_NO_ERROR, fmt, ap);
}
void
throw_error (enum errors error, const char *fmt, ...)
{
va_list args;
va_start (args, fmt);
throw_verror (error, fmt, args);
va_end (args);
}
void
throw_quit (const char *fmt, ...)
{
va_list args;
va_start (args, fmt);
throw_vquit (fmt, args);
va_end (args);
}
/* Call FUNC(UIOUT, FUNC_ARGS) but wrapped within an exception
handler. If an exception (enum return_reason) is thrown using
throw_exception() than all cleanups installed since
catch_exceptions() was entered are invoked, the (-ve) exception
value is then returned by catch_exceptions. If FUNC() returns
normally (with a positive or zero return value) then that value is
returned by catch_exceptions(). It is an internal_error() for
FUNC() to return a negative value.
See exceptions.h for further usage details.
Must not be called with immediate_quit in effect (bad things might
happen, say we got a signal in the middle of a memcpy to quit_return).
This is an OK restriction; with very few exceptions immediate_quit can
be replaced by judicious use of QUIT. */
/* MAYBE: cagney/1999-11-05: catch_errors() in conjunction with
error() et al. could maintain a set of flags that indicate the
current state of each of the longjmp buffers. This would give the
longjmp code the chance to detect a longjmp botch (before it gets
to longjmperror()). Prior to 1999-11-05 this wasn't possible as
code also randomly used a SET_TOP_LEVEL macro that directly
initialized the longjmp buffers. */
int
catch_exceptions (struct ui_out *uiout,
catch_exceptions_ftype *func,
void *func_args,
return_mask mask)
{
return catch_exceptions_with_msg (uiout, func, func_args, NULL, mask);
}
int
catch_exceptions_with_msg (struct ui_out *func_uiout,
catch_exceptions_ftype *func,
void *func_args,
char **gdberrmsg,
return_mask mask)
{
volatile struct gdb_exception exception;
volatile int val = 0;
struct ui_out *saved_uiout;
/* Save and override the global ``struct ui_out'' builder. */
saved_uiout = current_uiout;
current_uiout = func_uiout;
TRY_CATCH (exception, RETURN_MASK_ALL)
{
val = (*func) (current_uiout, func_args);
}
/* Restore the global builder. */
current_uiout = saved_uiout;
if (exception.reason < 0 && (mask & RETURN_MASK (exception.reason)) == 0)
{
/* The caller didn't request that the event be caught.
Rethrow. */
throw_exception (exception);
}
exception_print (gdb_stderr, exception);
gdb_assert (val >= 0);
gdb_assert (exception.reason <= 0);
if (exception.reason < 0)
{
/* If caller wants a copy of the low-level error message, make
one. This is used in the case of a silent error whereby the
caller may optionally want to issue the message. */
if (gdberrmsg != NULL)
{
if (exception.message != NULL)
*gdberrmsg = xstrdup (exception.message);
else
*gdberrmsg = NULL;
}
return exception.reason;
}
return val;
}
/* This function is superseded by catch_exceptions(). */
int
catch_errors (catch_errors_ftype *func, void *func_args, char *errstring,
return_mask mask)
{
volatile int val = 0;
volatile struct gdb_exception exception;
struct ui_out *saved_uiout;
/* Save the global ``struct ui_out'' builder. */
saved_uiout = current_uiout;
TRY_CATCH (exception, RETURN_MASK_ALL)
{
val = func (func_args);
}
/* Restore the global builder. */
current_uiout = saved_uiout;
if (exception.reason < 0 && (mask & RETURN_MASK (exception.reason)) == 0)
{
/* The caller didn't request that the event be caught.
Rethrow. */
throw_exception (exception);
}
exception_fprintf (gdb_stderr, exception, "%s", errstring);
if (exception.reason != 0)
return 0;
return val;
}