aboutsummaryrefslogtreecommitdiff
path: root/gdb/guile/scm-breakpoint.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@adacore.com>2019-04-24 06:50:01 -0600
committerTom Tromey <tromey@adacore.com>2019-04-25 12:59:35 -0600
commit680d7fd5fcff860a31021845389d4dfeb7b42e3c (patch)
tree0065f8d560b3148a3a3dceb5e3e34ab724cc7cba /gdb/guile/scm-breakpoint.c
parentc6fdd8b2052baa9b7a27d4d34f109c9622b53509 (diff)
downloadgdb-680d7fd5fcff860a31021845389d4dfeb7b42e3c.zip
gdb-680d7fd5fcff860a31021845389d4dfeb7b42e3c.tar.gz
gdb-680d7fd5fcff860a31021845389d4dfeb7b42e3c.tar.bz2
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 <tromey@adacore.com> * 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.
Diffstat (limited to 'gdb/guile/scm-breakpoint.c')
-rw-r--r--gdb/guile/scm-breakpoint.c33
1 files changed, 23 insertions, 10 deletions
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;