diff options
author | Tom Tromey <tromey@adacore.com> | 2019-04-24 06:50:01 -0600 |
---|---|---|
committer | Tom Tromey <tromey@adacore.com> | 2019-04-25 12:59:35 -0600 |
commit | 680d7fd5fcff860a31021845389d4dfeb7b42e3c (patch) | |
tree | 0065f8d560b3148a3a3dceb5e3e34ab724cc7cba /gdb/guile/scm-type.c | |
parent | c6fdd8b2052baa9b7a27d4d34f109c9622b53509 (diff) | |
download | fsf-binutils-gdb-680d7fd5fcff860a31021845389d4dfeb7b42e3c.zip fsf-binutils-gdb-680d7fd5fcff860a31021845389d4dfeb7b42e3c.tar.gz fsf-binutils-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-type.c')
-rw-r--r-- | gdb/guile/scm-type.c | 42 |
1 files changed, 30 insertions, 12 deletions
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); } |