diff options
author | Tom Tromey <tromey@redhat.com> | 2013-04-15 18:09:02 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2013-04-15 18:09:02 +0000 |
commit | 72f1fe8a88c4dc9219c4263eff2bbcf61173e607 (patch) | |
tree | a0500c8be84baf95cff28fb6f70b240be4de4f44 /gdb/break-catch-throw.c | |
parent | * break-catch-throw.c (struct exception_names): New. (diff) | |
download | binutils-gdb-72f1fe8a88c4dc9219c4263eff2bbcf61173e607.tar.gz binutils-gdb-72f1fe8a88c4dc9219c4263eff2bbcf61173e607.tar.bz2 binutils-gdb-72f1fe8a88c4dc9219c4263eff2bbcf61173e607.zip |
PR c++/15176:
* NEWS: Update.
* break-catch-throw.c (compute_exception): New function.
(exception_funcs): New global.
(_initialize_break_catch_throw): Create $_exception.
* cp-abi.c (cplus_type_from_type_info): New function.
* cp-abi.h (cplus_type_from_type_info): Declare.
(struct cp_abi_ops) <get_type_from_type_info>: New field.
* gnu-v3-abi.c (gnuv3_get_typename_from_type_info)
(gnuv3_get_type_from_type_info): New functions.
(init_gnuv3_ops): Set get_type_from_type_info ABI field.
gdb/doc
* gdb.texinfo (Set Catchpoints): Document $_exception.
(Convenience Vars): Mention $_exception.
gdb/testsuite
* gdb.base/default.exp: Update for $_exception.
* gdb.cp/exceptprint.cc: New file.
* gdb.cp/exceptprint.exp: New file.
* lib/gdb.exp (skip_libstdcxx_probe_tests): New proc.
Diffstat (limited to 'gdb/break-catch-throw.c')
-rw-r--r-- | gdb/break-catch-throw.c | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c index 8b9b837f9fd..ed236ef20bf 100644 --- a/gdb/break-catch-throw.c +++ b/gdb/break-catch-throw.c @@ -32,6 +32,8 @@ #include "exceptions.h" #include "linespec.h" #include "probe.h" +#include "objfiles.h" +#include "cp-abi.h" /* Enums for exception-handling support. */ enum exception_event_kind @@ -327,6 +329,61 @@ catch_rethrow_command (char *arg, int from_tty, +/* Implement the 'make_value' method for the $_exception + internalvar. */ + +static struct value * +compute_exception (struct gdbarch *argc, struct internalvar *var, void *ignore) +{ + struct frame_info *frame = get_selected_frame (_("No frame selected")); + CORE_ADDR pc = get_frame_pc (frame); + struct probe *pc_probe; + const struct sym_probe_fns *pc_probe_fns; + unsigned n_args; + struct value *arg0, *arg1; + struct type *obj_type; + + pc_probe = find_probe_by_pc (pc); + if (pc_probe == NULL + || strcmp (pc_probe->provider, "libstdcxx") != 0 + || (strcmp (pc_probe->name, "catch") != 0 + && strcmp (pc_probe->name, "throw") != 0 + && strcmp (pc_probe->name, "rethrow") != 0)) + error (_("not stopped at a C++ exception catchpoint")); + + gdb_assert (pc_probe->objfile != NULL); + gdb_assert (pc_probe->objfile->sf != NULL); + gdb_assert (pc_probe->objfile->sf->sym_probe_fns != NULL); + + pc_probe_fns = pc_probe->objfile->sf->sym_probe_fns; + n_args = pc_probe_fns->sym_get_probe_argument_count (pc_probe); + if (n_args < 2) + error (_("C++ exception catchpoint has too few arguments")); + + arg0 = pc_probe_fns->sym_evaluate_probe_argument (pc_probe, 0); + arg1 = pc_probe_fns->sym_evaluate_probe_argument (pc_probe, 1); + + if (arg0 == NULL || arg1 == NULL) + error (_("error computing probe argument at c++ exception catchpoint")); + + /* ARG0 is a pointer to the exception object. ARG1 is a pointer to + the std::type_info for the exception. Now we find the type from + the type_info and cast the result. */ + obj_type = cplus_type_from_type_info (arg1); + return value_ind (value_cast (make_pointer_type (obj_type, NULL), arg0)); +} + +/* Implementation of the '$_exception' variable. */ + +static const struct internalvar_funcs exception_funcs = +{ + compute_exception, + NULL, + NULL +}; + + + static void initialize_throw_catchpoint_ops (void) { @@ -370,4 +427,6 @@ Catch an exception, when rethrown."), NULL, CATCH_PERMANENT, CATCH_TEMPORARY); + + create_internalvar_type_lazy ("_exception", &exception_funcs, NULL); } |