From 680d7fd5fcff860a31021845389d4dfeb7b42e3c Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 24 Apr 2019 06:50:01 -0600 Subject: [PATCH] Avoid undefined behavior in Guile exception handling The Guile code will longjmp (via scm_throw) when an object requiring destruction is on the stack. This is undefined behavior. This changes this code to run any destructors in inner scopes, and to pass a POD to gdbscm_throw_gdb_exception. gdb/ChangeLog 2019-04-25 Tom Tromey * guile/scm-exception.c (gdbscm_scm_from_gdb_exception) (gdbscm_throw_gdb_exception): Take a gdbscm_gdb_exception. * guile/scm-block.c, guile/scm-breakpoint.c, guile/scm-cmd.c, guile/scm-disasm.c, guile/scm-frame.c, guile/scm-lazy-string.c, guile/scm-math.c, guile/scm-param.c, guile/scm-ports.c, guile/scm-symbol.c, guile/scm-symtab.c, guile/scm-type.c, guile/scm-value.c: Use unpack. * guile/guile-internal.h (gdbscm_scm_from_gdb_exception): Take a gdbscm_gdb_exception. (gdbscm_throw_gdb_exception): Likewise. (struct gdbscm_gdb_exception): New. (unpack): New function. (gdbscm_wrap): Use unpack. --- gdb/ChangeLog | 16 ++++++++++ gdb/guile/guile-internal.h | 38 +++++++++++++++++++++-- gdb/guile/scm-block.c | 4 ++- gdb/guile/scm-breakpoint.c | 33 +++++++++++++------- gdb/guile/scm-cmd.c | 4 ++- gdb/guile/scm-disasm.c | 4 ++- gdb/guile/scm-exception.c | 10 ++++--- gdb/guile/scm-frame.c | 73 ++++++++++++++++++++++++++++++++------------- gdb/guile/scm-lazy-string.c | 2 +- gdb/guile/scm-math.c | 2 +- gdb/guile/scm-param.c | 8 +++-- gdb/guile/scm-ports.c | 4 ++- gdb/guile/scm-symbol.c | 20 ++++++++----- gdb/guile/scm-symtab.c | 4 ++- gdb/guile/scm-type.c | 42 ++++++++++++++++++-------- gdb/guile/scm-value.c | 53 ++++++++++++++++++++++---------- 16 files changed, 235 insertions(+), 82 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 809df46..ce3ea81 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,21 @@ 2019-04-25 Tom Tromey + * guile/scm-exception.c (gdbscm_scm_from_gdb_exception) + (gdbscm_throw_gdb_exception): Take a gdbscm_gdb_exception. + * guile/scm-block.c, guile/scm-breakpoint.c, guile/scm-cmd.c, + guile/scm-disasm.c, guile/scm-frame.c, guile/scm-lazy-string.c, + guile/scm-math.c, guile/scm-param.c, guile/scm-ports.c, + guile/scm-symbol.c, guile/scm-symtab.c, guile/scm-type.c, + guile/scm-value.c: Use unpack. + * guile/guile-internal.h (gdbscm_scm_from_gdb_exception): Take a + gdbscm_gdb_exception. + (gdbscm_throw_gdb_exception): Likewise. + (struct gdbscm_gdb_exception): New. + (unpack): New function. + (gdbscm_wrap): Use unpack. + +2019-04-25 Tom Tromey + * event-top.c (gdb_rl_callback_read_char_wrapper_noexcept) (gdb_rl_callback_handler): Use std::move. * common/common-exceptions.h (struct gdb_exception): Add move diff --git a/gdb/guile/guile-internal.h b/gdb/guile/guile-internal.h index a3e02ab..8ea8706 100644 --- a/gdb/guile/guile-internal.h +++ b/gdb/guile/guile-internal.h @@ -353,9 +353,11 @@ extern void gdbscm_misc_error (const char *subr, int arg_pos, extern void gdbscm_throw (SCM exception) ATTRIBUTE_NORETURN; -extern SCM gdbscm_scm_from_gdb_exception (struct gdb_exception exception); +struct gdbscm_gdb_exception; +extern SCM gdbscm_scm_from_gdb_exception + (const gdbscm_gdb_exception &exception); -extern void gdbscm_throw_gdb_exception (struct gdb_exception exception) +extern void gdbscm_throw_gdb_exception (gdbscm_gdb_exception exception) ATTRIBUTE_NORETURN; extern void gdbscm_print_exception_with_stack (SCM port, SCM stack, @@ -650,6 +652,33 @@ extern void gdbscm_initialize_values (void); with a TRY/CATCH, because the dtors won't otherwise be run when a Guile exceptions is thrown. */ +/* This is a destructor-less clone of gdb_exception. */ + +struct gdbscm_gdb_exception +{ + enum return_reason reason; + enum errors error; + /* The message is xmalloc'd. */ + char *message; +}; + +/* Return a gdbscm_gdb_exception representing EXC. */ + +inline gdbscm_gdb_exception +unpack (const gdb_exception &exc) +{ + gdbscm_gdb_exception result; + result.reason = exc.reason; + result.error = exc.error; + if (exc.message == nullptr) + result.message = nullptr; + else + result.message = xstrdup (exc.message->c_str ()); + /* The message should be NULL iff the reason is zero. */ + gdb_assert ((result.reason == 0) == (result.message == nullptr)); + return result; +} + /* Use this after a TRY/CATCH to throw the appropriate Scheme exception if a GDB error occurred. */ @@ -676,6 +705,7 @@ SCM gdbscm_wrap (Function &&func, Args &&... args) { SCM result = SCM_BOOL_F; + gdbscm_gdb_exception exc {}; try { @@ -683,9 +713,11 @@ gdbscm_wrap (Function &&func, Args &&... args) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); + if (gdbscm_is_exception (result)) gdbscm_throw (result); diff --git a/gdb/guile/scm-block.c b/gdb/guile/scm-block.c index 2114ca1..fbb2f4a 100644 --- a/gdb/guile/scm-block.c +++ b/gdb/guile/scm-block.c @@ -680,6 +680,7 @@ gdbscm_lookup_block (SCM pc_scm) gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, NULL, "U", pc_scm, &pc); + gdbscm_gdb_exception exc {}; try { cust = find_pc_compunit_symtab (pc); @@ -689,9 +690,10 @@ gdbscm_lookup_block (SCM pc_scm) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (cust == NULL || COMPUNIT_OBJFILE (cust) == NULL) { gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, pc_scm, diff --git a/gdb/guile/scm-breakpoint.c b/gdb/guile/scm-breakpoint.c index f86c263..9a4efee 100644 --- a/gdb/guile/scm-breakpoint.c +++ b/gdb/guile/scm-breakpoint.c @@ -411,7 +411,7 @@ gdbscm_register_breakpoint_x (SCM self) { breakpoint_smob *bp_smob = bpscm_get_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); - struct gdb_exception except; + gdbscm_gdb_exception except {}; const char *location, *copy; /* We only support registering breakpoints created with make-breakpoint. */ @@ -467,7 +467,7 @@ gdbscm_register_breakpoint_x (SCM self) } catch (const gdb_exception &ex) { - except = ex; + except = unpack (ex); } /* Ensure this gets reset, even if there's an error. */ @@ -489,15 +489,17 @@ gdbscm_delete_breakpoint_x (SCM self) breakpoint_smob *bp_smob = bpscm_get_valid_breakpoint_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); + gdbscm_gdb_exception exc {}; try { delete_breakpoint (bp_smob->bp); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return SCM_UNSPECIFIED; } @@ -586,6 +588,7 @@ gdbscm_set_breakpoint_enabled_x (SCM self, SCM newvalue) SCM_ASSERT_TYPE (gdbscm_is_bool (newvalue), newvalue, SCM_ARG2, FUNC_NAME, _("boolean")); + gdbscm_gdb_exception exc {}; try { if (gdbscm_is_true (newvalue)) @@ -595,9 +598,10 @@ gdbscm_set_breakpoint_enabled_x (SCM self, SCM newvalue) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return SCM_UNSPECIFIED; } @@ -623,15 +627,17 @@ gdbscm_set_breakpoint_silent_x (SCM self, SCM newvalue) SCM_ASSERT_TYPE (gdbscm_is_bool (newvalue), newvalue, SCM_ARG2, FUNC_NAME, _("boolean")); + gdbscm_gdb_exception exc {}; try { breakpoint_set_silent (bp_smob->bp, gdbscm_is_true (newvalue)); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return SCM_UNSPECIFIED; } @@ -663,15 +669,17 @@ gdbscm_set_breakpoint_ignore_count_x (SCM self, SCM newvalue) if (value < 0) value = 0; + gdbscm_gdb_exception exc {}; try { set_ignore_count (bp_smob->number, (int) value, 0); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return SCM_UNSPECIFIED; } @@ -783,15 +791,17 @@ gdbscm_set_breakpoint_task_x (SCM self, SCM newvalue) { id = scm_to_long (newvalue); + gdbscm_gdb_exception exc {}; try { valid_id = valid_task_id (id); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (! valid_id) { gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG2, newvalue, @@ -803,15 +813,17 @@ gdbscm_set_breakpoint_task_x (SCM self, SCM newvalue) else SCM_ASSERT_TYPE (0, newvalue, SCM_ARG2, FUNC_NAME, _("integer or #f")); + gdbscm_gdb_exception exc {}; try { breakpoint_set_task (bp_smob->bp, id); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return SCM_UNSPECIFIED; } @@ -968,17 +980,18 @@ gdbscm_breakpoint_commands (SCM self) string_file buf; current_uiout->redirect (&buf); + gdbscm_gdb_exception exc {}; try { print_command_lines (current_uiout, breakpoint_commands (bp), 0); } catch (const gdb_exception &except) { - current_uiout->redirect (NULL); - gdbscm_throw_gdb_exception (except); + exc = unpack (except); } current_uiout->redirect (NULL); + GDBSCM_HANDLE_GDB_EXCEPTION (exc); result = gdbscm_scm_from_c_string (buf.c_str ()); return result; diff --git a/gdb/guile/scm-cmd.c b/gdb/guile/scm-cmd.c index 38db7f5..f2fa40e 100644 --- a/gdb/guile/scm-cmd.c +++ b/gdb/guile/scm-cmd.c @@ -758,6 +758,7 @@ gdbscm_register_command_x (SCM self) c_smob->cmd_name = gdbscm_gc_xstrdup (cmd_name); xfree (cmd_name); + gdbscm_gdb_exception exc {}; try { if (c_smob->is_prefix) @@ -778,8 +779,9 @@ gdbscm_register_command_x (SCM self) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); /* Note: At this point the command exists in gdb. So no more errors after this point. */ diff --git a/gdb/guile/scm-disasm.c b/gdb/guile/scm-disasm.c index d673a1e..6b34a22 100644 --- a/gdb/guile/scm-disasm.c +++ b/gdb/guile/scm-disasm.c @@ -247,6 +247,7 @@ gdbscm_arch_disassemble (SCM self, SCM start_scm, SCM rest) int insn_len = 0; string_file buf; + gdbscm_gdb_exception exc {}; try { if (using_port) @@ -259,9 +260,10 @@ gdbscm_arch_disassemble (SCM self, SCM start_scm, SCM rest) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); result = scm_cons (dascm_make_insn (pc, buf.c_str (), insn_len), result); diff --git a/gdb/guile/scm-exception.c b/gdb/guile/scm-exception.c index 44cd7b3..e519ad8 100644 --- a/gdb/guile/scm-exception.c +++ b/gdb/guile/scm-exception.c @@ -428,7 +428,7 @@ gdbscm_throw (SCM exception) /* Convert a GDB exception to a object. */ SCM -gdbscm_scm_from_gdb_exception (struct gdb_exception exception) +gdbscm_scm_from_gdb_exception (const gdbscm_gdb_exception &exception) { SCM key; @@ -446,7 +446,7 @@ gdbscm_scm_from_gdb_exception (struct gdb_exception exception) return gdbscm_make_error (key, NULL, "~A", scm_list_1 (gdbscm_scm_from_c_string - (exception.what ())), + (exception.message)), SCM_BOOL_F); } @@ -454,9 +454,11 @@ gdbscm_scm_from_gdb_exception (struct gdb_exception exception) This function does not return. */ void -gdbscm_throw_gdb_exception (struct gdb_exception exception) +gdbscm_throw_gdb_exception (gdbscm_gdb_exception exception) { - gdbscm_throw (gdbscm_scm_from_gdb_exception (exception)); + SCM scm_exception = gdbscm_scm_from_gdb_exception (exception); + xfree (exception.message); + gdbscm_throw (scm_exception); } /* Print the error message portion of an exception. diff --git a/gdb/guile/scm-frame.c b/gdb/guile/scm-frame.c index f3795f8..0345ac6 100644 --- a/gdb/guile/scm-frame.c +++ b/gdb/guile/scm-frame.c @@ -250,7 +250,7 @@ frscm_scm_from_frame (struct frame_info *frame, struct inferior *inferior) } catch (const gdb_exception &except) { - return gdbscm_scm_from_gdb_exception (except); + return gdbscm_scm_from_gdb_exception (unpack (except)); } f_scm = frscm_make_frame_smob (); @@ -396,15 +396,17 @@ gdbscm_frame_valid_p (SCM self) f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); + gdbscm_gdb_exception exc {}; try { frame = frscm_frame_smob_to_frame (f_smob); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return scm_from_bool (frame != NULL); } @@ -423,6 +425,7 @@ gdbscm_frame_name (SCM self) f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); + gdbscm_gdb_exception exc {}; try { frame = frscm_frame_smob_to_frame (f_smob); @@ -431,9 +434,10 @@ gdbscm_frame_name (SCM self) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (frame == NULL) { gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, @@ -460,6 +464,7 @@ gdbscm_frame_type (SCM self) f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); + gdbscm_gdb_exception exc {}; try { frame = frscm_frame_smob_to_frame (f_smob); @@ -468,9 +473,10 @@ gdbscm_frame_type (SCM self) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (frame == NULL) { gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, @@ -491,15 +497,17 @@ gdbscm_frame_arch (SCM self) f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); + gdbscm_gdb_exception exc {}; try { frame = frscm_frame_smob_to_frame (f_smob); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (frame == NULL) { gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, @@ -521,15 +529,17 @@ gdbscm_frame_unwind_stop_reason (SCM self) f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); + gdbscm_gdb_exception exc {}; try { frame = frscm_frame_smob_to_frame (f_smob); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (frame == NULL) { gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, @@ -553,6 +563,7 @@ gdbscm_frame_pc (SCM self) f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); + gdbscm_gdb_exception exc {}; try { frame = frscm_frame_smob_to_frame (f_smob); @@ -561,9 +572,10 @@ gdbscm_frame_pc (SCM self) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (frame == NULL) { gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, @@ -585,6 +597,7 @@ gdbscm_frame_block (SCM self) f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); + gdbscm_gdb_exception exc {}; try { frame = frscm_frame_smob_to_frame (f_smob); @@ -593,9 +606,10 @@ gdbscm_frame_block (SCM self) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (frame == NULL) { gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, @@ -635,6 +649,7 @@ gdbscm_frame_function (SCM self) f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); + gdbscm_gdb_exception exc {}; try { frame = frscm_frame_smob_to_frame (f_smob); @@ -643,9 +658,10 @@ gdbscm_frame_function (SCM self) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (frame == NULL) { gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, @@ -671,6 +687,7 @@ gdbscm_frame_older (SCM self) f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); + gdbscm_gdb_exception exc {}; try { frame = frscm_frame_smob_to_frame (f_smob); @@ -679,9 +696,10 @@ gdbscm_frame_older (SCM self) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (frame == NULL) { gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, @@ -707,6 +725,7 @@ gdbscm_frame_newer (SCM self) f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); + gdbscm_gdb_exception exc {}; try { frame = frscm_frame_smob_to_frame (f_smob); @@ -715,9 +734,10 @@ gdbscm_frame_newer (SCM self) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (frame == NULL) { gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, @@ -742,6 +762,7 @@ gdbscm_frame_sal (SCM self) f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); + gdbscm_gdb_exception exc {}; try { frame = frscm_frame_smob_to_frame (f_smob); @@ -750,9 +771,10 @@ gdbscm_frame_sal (SCM self) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (frame == NULL) { gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, @@ -777,7 +799,7 @@ gdbscm_frame_read_register (SCM self, SCM register_scm) gdbscm_parse_function_args (FUNC_NAME, SCM_ARG2, NULL, "s", register_scm, ®ister_str); - struct gdb_exception except; + gdbscm_gdb_exception except {}; try { @@ -795,7 +817,7 @@ gdbscm_frame_read_register (SCM self, SCM register_scm) } catch (const gdb_exception &ex) { - except = ex; + except = unpack (ex); } xfree (register_str); @@ -838,15 +860,17 @@ gdbscm_frame_read_var (SCM self, SCM symbol_scm, SCM rest) f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); + gdbscm_gdb_exception exc {}; try { frame = frscm_frame_smob_to_frame (f_smob); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (frame == NULL) { gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, @@ -864,7 +888,7 @@ gdbscm_frame_read_var (SCM self, SCM symbol_scm, SCM rest) } else if (scm_is_string (symbol_scm)) { - struct gdb_exception except; + gdbscm_gdb_exception except {}; if (! SCM_UNBNDP (block_scm)) { @@ -896,7 +920,7 @@ gdbscm_frame_read_var (SCM self, SCM symbol_scm, SCM rest) } catch (const gdb_exception &ex) { - except = ex; + except = unpack (ex); } } @@ -919,9 +943,10 @@ gdbscm_frame_read_var (SCM self, SCM symbol_scm, SCM rest) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return vlscm_scm_from_value (value); } @@ -936,6 +961,7 @@ gdbscm_frame_select (SCM self) f_smob = frscm_get_frame_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); + gdbscm_gdb_exception exc {}; try { frame = frscm_frame_smob_to_frame (f_smob); @@ -944,9 +970,10 @@ gdbscm_frame_select (SCM self) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (frame == NULL) { gdbscm_invalid_object_error (FUNC_NAME, SCM_ARG1, self, @@ -964,15 +991,17 @@ gdbscm_newest_frame (void) { struct frame_info *frame = NULL; + gdbscm_gdb_exception exc {}; try { frame = get_current_frame (); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return frscm_scm_from_frame_unsafe (frame, current_inferior ()); } @@ -984,15 +1013,17 @@ gdbscm_selected_frame (void) { struct frame_info *frame = NULL; + gdbscm_gdb_exception exc {}; try { frame = get_selected_frame (_("No frame is currently selected")); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return frscm_scm_from_frame_unsafe (frame, current_inferior ()); } diff --git a/gdb/guile/scm-lazy-string.c b/gdb/guile/scm-lazy-string.c index 4d69b23..b0bbc82 100644 --- a/gdb/guile/scm-lazy-string.c +++ b/gdb/guile/scm-lazy-string.c @@ -338,7 +338,7 @@ lsscm_safe_lazy_string_to_value (SCM string, int arg_pos, } catch (const gdb_exception &except) { - *except_scmp = gdbscm_scm_from_gdb_exception (except); + *except_scmp = gdbscm_scm_from_gdb_exception (unpack (except)); return NULL; } diff --git a/gdb/guile/scm-math.c b/gdb/guile/scm-math.c index dc7245b..35ad4aa 100644 --- a/gdb/guile/scm-math.c +++ b/gdb/guile/scm-math.c @@ -826,7 +826,7 @@ vlscm_convert_typed_value_from_scheme (const char *func_name, } catch (const gdb_exception &except) { - except_scm = gdbscm_scm_from_gdb_exception (except); + except_scm = gdbscm_scm_from_gdb_exception (unpack (except)); } if (gdbscm_is_true (except_scm)) diff --git a/gdb/guile/scm-param.c b/gdb/guile/scm-param.c index cc10806..53120cb 100644 --- a/gdb/guile/scm-param.c +++ b/gdb/guile/scm-param.c @@ -1006,6 +1006,7 @@ gdbscm_register_parameter_x (SCM self) _("parameter exists, \"show\" command is already defined")); } + gdbscm_gdb_exception exc {}; try { add_setshow_generic (p_smob->type, p_smob->cmd_class, @@ -1020,9 +1021,10 @@ gdbscm_register_parameter_x (SCM self) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); /* Note: At this point the parameter exists in gdb. So no more errors after this point. */ @@ -1056,7 +1058,7 @@ gdbscm_parameter_value (SCM self) struct cmd_list_element *alias, *prefix, *cmd; char *newarg; int found = -1; - struct gdb_exception except; + gdbscm_gdb_exception except {}; gdb::unique_xmalloc_ptr name = gdbscm_scm_to_host_string (self, NULL, &except_scm); @@ -1069,7 +1071,7 @@ gdbscm_parameter_value (SCM self) } catch (const gdb_exception &ex) { - except = ex; + except = unpack (ex); } xfree (newarg); diff --git a/gdb/guile/scm-ports.c b/gdb/guile/scm-ports.c index 57d3b18..114b358 100644 --- a/gdb/guile/scm-ports.c +++ b/gdb/guile/scm-ports.c @@ -272,6 +272,7 @@ ioscm_write (SCM port, const void *data, size_t size) if (scm_is_eq (port, input_port_scm)) return; + gdbscm_gdb_exception exc {}; try { if (scm_is_eq (port, error_port_scm)) @@ -281,8 +282,9 @@ ioscm_write (SCM port, const void *data, size_t size) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); } /* Flush gdb's stdout or stderr. */ diff --git a/gdb/guile/scm-symbol.c b/gdb/guile/scm-symbol.c index ab39123..7b44b56 100644 --- a/gdb/guile/scm-symbol.c +++ b/gdb/guile/scm-symbol.c @@ -486,15 +486,17 @@ gdbscm_symbol_needs_frame_p (SCM self) struct symbol *symbol = s_smob->symbol; int result = 0; + gdbscm_gdb_exception exc {}; try { result = symbol_read_needs_frame (symbol); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return scm_from_bool (result); } @@ -538,6 +540,7 @@ gdbscm_symbol_value (SCM self, SCM rest) _("cannot get the value of a typedef")); } + gdbscm_gdb_exception exc {}; try { if (f_smob != NULL) @@ -558,9 +561,10 @@ gdbscm_symbol_value (SCM self, SCM rest) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return vlscm_scm_from_value (value); } @@ -602,6 +606,7 @@ gdbscm_lookup_symbol (SCM name_scm, SCM rest) { struct frame_info *selected_frame; + gdbscm_gdb_exception exc {}; try { selected_frame = get_selected_frame (_("no frame selected")); @@ -610,11 +615,12 @@ gdbscm_lookup_symbol (SCM name_scm, SCM rest) catch (const gdb_exception &ex) { xfree (name); - GDBSCM_HANDLE_GDB_EXCEPTION (ex); + exc = unpack (ex); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); } - struct gdb_exception except; + gdbscm_gdb_exception except {}; try { symbol = lookup_symbol (name, block, (domain_enum) domain, @@ -622,7 +628,7 @@ gdbscm_lookup_symbol (SCM name_scm, SCM rest) } catch (const gdb_exception &ex) { - except = ex; + except = unpack (ex); } xfree (name); @@ -646,7 +652,7 @@ gdbscm_lookup_global_symbol (SCM name_scm, SCM rest) int domain_arg_pos = -1; int domain = VAR_DOMAIN; struct symbol *symbol = NULL; - struct gdb_exception except; + gdbscm_gdb_exception except {}; gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, keywords, "s#i", name_scm, &name, rest, @@ -658,7 +664,7 @@ gdbscm_lookup_global_symbol (SCM name_scm, SCM rest) } catch (const gdb_exception &ex) { - except = ex; + except = unpack (ex); } xfree (name); diff --git a/gdb/guile/scm-symtab.c b/gdb/guile/scm-symtab.c index 60ed707..e55e49b 100644 --- a/gdb/guile/scm-symtab.c +++ b/gdb/guile/scm-symtab.c @@ -591,6 +591,7 @@ gdbscm_find_pc_line (SCM pc_scm) gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, NULL, "U", pc_scm, &pc_ull); + gdbscm_gdb_exception exc {}; try { CORE_ADDR pc = (CORE_ADDR) pc_ull; @@ -599,9 +600,10 @@ gdbscm_find_pc_line (SCM pc_scm) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return stscm_scm_from_sal (sal); } diff --git a/gdb/guile/scm-type.c b/gdb/guile/scm-type.c index 8f47ef6..5b99da7 100644 --- a/gdb/guile/scm-type.c +++ b/gdb/guile/scm-type.c @@ -105,6 +105,7 @@ tyscm_type_smob_type (type_smob *t_smob) static std::string tyscm_type_name (struct type *type) { + SCM excp; try { string_file stb; @@ -114,11 +115,10 @@ tyscm_type_name (struct type *type) } catch (const gdb_exception &except) { - SCM excp = gdbscm_scm_from_gdb_exception (except); - gdbscm_throw (excp); + excp = gdbscm_scm_from_gdb_exception (unpack (except)); } - gdb_assert_not_reached ("no way to get here"); + gdbscm_throw (excp); } /* Administrivia for type smobs. */ @@ -234,15 +234,17 @@ tyscm_equal_p_type_smob (SCM type1_scm, SCM type2_scm) type1 = type1_smob->type; type2 = type2_smob->type; + gdbscm_gdb_exception exc {}; try { result = types_deeply_equal (type1, type2); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return scm_from_bool (result); } @@ -650,15 +652,17 @@ gdbscm_type_strip_typedefs (SCM self) = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); struct type *type = t_smob->type; + gdbscm_gdb_exception exc {}; try { type = check_typedef (type); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return tyscm_scm_from_type (type); } @@ -671,15 +675,17 @@ tyscm_get_composite (struct type *type) for (;;) { + gdbscm_gdb_exception exc {}; try { type = check_typedef (type); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (TYPE_CODE (type) != TYPE_CODE_PTR && TYPE_CODE (type) != TYPE_CODE_REF) break; @@ -725,6 +731,7 @@ tyscm_array_1 (SCM self, SCM n1_scm, SCM n2_scm, int is_vector, _("Array length must not be negative")); } + gdbscm_gdb_exception exc {}; try { array = lookup_array_range_type (type, n1, n2); @@ -733,9 +740,10 @@ tyscm_array_1 (SCM self, SCM n1_scm, SCM n2_scm, int is_vector, } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return tyscm_scm_from_type (array); } @@ -781,15 +789,17 @@ gdbscm_type_pointer (SCM self) = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); struct type *type = t_smob->type; + gdbscm_gdb_exception exc {}; try { type = lookup_pointer_type (type); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return tyscm_scm_from_type (type); } @@ -842,15 +852,17 @@ gdbscm_type_reference (SCM self) = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); struct type *type = t_smob->type; + gdbscm_gdb_exception exc {}; try { type = lookup_lvalue_reference_type (type); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return tyscm_scm_from_type (type); } @@ -879,15 +891,17 @@ gdbscm_type_const (SCM self) = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); struct type *type = t_smob->type; + gdbscm_gdb_exception exc {}; try { type = make_cv_type (1, 0, type, NULL); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return tyscm_scm_from_type (type); } @@ -901,15 +915,17 @@ gdbscm_type_volatile (SCM self) = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); struct type *type = t_smob->type; + gdbscm_gdb_exception exc {}; try { type = make_cv_type (0, 1, type, NULL); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return tyscm_scm_from_type (type); } @@ -923,15 +939,17 @@ gdbscm_type_unqualified (SCM self) = tyscm_get_type_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); struct type *type = t_smob->type; + gdbscm_gdb_exception exc {}; try { type = make_cv_type (0, 0, type, NULL); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return tyscm_scm_from_type (type); } diff --git a/gdb/guile/scm-value.c b/gdb/guile/scm-value.c index 00d1c18..9b38210 100644 --- a/gdb/guile/scm-value.c +++ b/gdb/guile/scm-value.c @@ -156,6 +156,7 @@ vlscm_print_value_smob (SCM self, SCM port, scm_print_state *pstate) instead of writingp. */ opts.raw = !!pstate->writingp; + gdbscm_gdb_exception exc {}; try { string_file stb; @@ -165,9 +166,10 @@ vlscm_print_value_smob (SCM self, SCM port, scm_print_state *pstate) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (pstate->writingp) scm_puts (">", port); @@ -186,15 +188,17 @@ vlscm_equal_p_value_smob (SCM v1, SCM v2) const value_smob *v2_smob = (value_smob *) SCM_SMOB_DATA (v2); int result = 0; + gdbscm_gdb_exception exc {}; try { result = value_equal (v1_smob->value, v2_smob->value); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return scm_from_bool (result); } @@ -493,6 +497,7 @@ gdbscm_value_dynamic_type (SCM self) if (! SCM_UNBNDP (v_smob->dynamic_type)) return v_smob->dynamic_type; + gdbscm_gdb_exception exc {}; try { scoped_value_mark free_values; @@ -531,9 +536,10 @@ gdbscm_value_dynamic_type (SCM self) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (type == NULL) v_smob->dynamic_type = gdbscm_value_type (self); else @@ -680,15 +686,17 @@ gdbscm_value_call (SCM self, SCM args) long args_count; struct value **vargs = NULL; + gdbscm_gdb_exception exc {}; try { ftype = check_typedef (value_type (function)); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); SCM_ASSERT_TYPE (TYPE_CODE (ftype) == TYPE_CODE_FUNC, self, SCM_ARG1, FUNC_NAME, _("function (value of TYPE_CODE_FUNC)")); @@ -746,6 +754,7 @@ gdbscm_value_to_bytevector (SCM self) type = value_type (value); + gdbscm_gdb_exception exc {}; try { type = check_typedef (type); @@ -754,9 +763,10 @@ gdbscm_value_to_bytevector (SCM self) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); bv = scm_c_make_bytevector (length); memcpy (SCM_BYTEVECTOR_CONTENTS (bv), contents, length); @@ -789,15 +799,17 @@ gdbscm_value_to_bool (SCM self) type = value_type (value); + gdbscm_gdb_exception exc {}; try { type = check_typedef (type); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); SCM_ASSERT_TYPE (is_intlike (type, 1), self, SCM_ARG1, FUNC_NAME, _("integer-like gdb value")); @@ -810,9 +822,10 @@ gdbscm_value_to_bool (SCM self) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); return scm_from_bool (l != 0); } @@ -830,15 +843,17 @@ gdbscm_value_to_integer (SCM self) type = value_type (value); + gdbscm_gdb_exception exc {}; try { type = check_typedef (type); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); SCM_ASSERT_TYPE (is_intlike (type, 1), self, SCM_ARG1, FUNC_NAME, _("integer-like gdb value")); @@ -851,9 +866,10 @@ gdbscm_value_to_integer (SCM self) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); if (TYPE_UNSIGNED (type)) return gdbscm_scm_from_ulongest (l); else @@ -875,15 +891,17 @@ gdbscm_value_to_real (SCM self) type = value_type (value); + gdbscm_gdb_exception exc {}; try { type = check_typedef (type); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); SCM_ASSERT_TYPE (is_intlike (type, 0) || TYPE_CODE (type) == TYPE_CODE_FLT, self, SCM_ARG1, FUNC_NAME, _("number")); @@ -907,9 +925,10 @@ gdbscm_value_to_real (SCM self) } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); /* TODO: Is there a better way to check if the value fits? */ if (!value_equal (value, check)) gdbscm_out_of_range_error (FUNC_NAME, SCM_ARG1, self, @@ -992,6 +1011,7 @@ gdbscm_value_to_string (SCM self, SCM rest) /* We don't assume anything about the result of scm_port_conversion_strategy. From this point on, if errors is not 'errors, use 'substitute. */ + gdbscm_gdb_exception exc {}; try { gdb::unique_xmalloc_ptr buffer; @@ -1001,8 +1021,9 @@ gdbscm_value_to_string (SCM self, SCM rest) catch (const gdb_exception &except) { xfree (encoding); - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); /* If errors is "error", scm_from_stringn may throw a Scheme exception. Make sure we don't leak. This is done via scm_dynwind_begin, et.al. */ @@ -1048,7 +1069,7 @@ gdbscm_value_to_lazy_string (SCM self, SCM rest) char *encoding = NULL; int length = -1; SCM result = SCM_BOOL_F; /* -Wall */ - struct gdb_exception except; + gdbscm_gdb_exception except {}; /* The sequencing here, as everywhere else, is important. We can't have existing cleanups when a Scheme exception is thrown. */ @@ -1121,7 +1142,7 @@ gdbscm_value_to_lazy_string (SCM self, SCM rest) } catch (const gdb_exception &ex) { - except = ex; + except = unpack (ex); } xfree (encoding); @@ -1177,15 +1198,17 @@ gdbscm_value_print (SCM self) string_file stb; + gdbscm_gdb_exception exc {}; try { common_val_print (value, &stb, 0, &opts, current_language); } catch (const gdb_exception &except) { - GDBSCM_HANDLE_GDB_EXCEPTION (except); + exc = unpack (except); } + GDBSCM_HANDLE_GDB_EXCEPTION (exc); /* Use SCM_FAILED_CONVERSION_QUESTION_MARK to ensure this doesn't throw an error if the encoding fails. IWBN to use scm_take_locale_string here, but we'd have to temporarily -- 2.7.4