aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2018-01-22 17:33:13 +0000
committerPedro Alves <palves@redhat.com>2018-01-22 17:33:13 +0000
commit5c319bb260fa9637048cfae5fceba807e7849b39 (patch)
tree7bf27c3636ad23d21de177a58eb699f9ffa08d42 /gdb/typeprint.c
parentMAINTAINERS: Update my company e-mail address (diff)
downloadbinutils-gdb-5c319bb260fa9637048cfae5fceba807e7849b39.tar.gz
binutils-gdb-5c319bb260fa9637048cfae5fceba807e7849b39.tar.bz2
binutils-gdb-5c319bb260fa9637048cfae5fceba807e7849b39.zip
Fix segfault with 'set print object on' + 'whatis <struct>' & co
Compiling GDB with a recent GCC exposes a problem: ../../gdb/typeprint.c: In function 'void whatis_exp(const char*, int)': ../../gdb/typeprint.c:515:12: warning: 'val' may be used uninitialized in this function [-Wmaybe-uninitialized] real_type = value_rtti_type (val, &full, &top, &using_enc); ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The warning is correct. There are indeed code paths that use uninitialized 'val', leading to crashes. Inside the value_rtti_indirect_type/value_rtti_type calls here in whatis_exp: if (opts.objectprint) { if (((TYPE_CODE (type) == TYPE_CODE_PTR) || TYPE_IS_REFERENCE (type)) && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT)) real_type = value_rtti_indirect_type (val, &full, &top, &using_enc); else if (TYPE_CODE (type) == TYPE_CODE_STRUCT) real_type = value_rtti_type (val, &full, &top, &using_enc); } We reach those calls above with "set print object on", and then with any of: (gdb) whatis struct some_structure_type (gdb) whatis struct some_structure_type * (gdb) whatis struct some_structure_type & because "whatis" with a type argument enters this branch: /* The behavior of "whatis" depends on whether the user expression names a type directly, or a language expression (including variable names). If the former, then "whatis" strips one level of typedefs, only. If an expression, "whatis" prints the type of the expression without stripping any typedef level. "ptype" always strips all levels of typedefs. */ if (show == -1 && expr->elts[0].opcode == OP_TYPE) { which does not initialize VAL. Trying the above triggers crashes like this: (gdb) set print object on (gdb) whatis some_structure_type Thread 1 "gdb" received signal SIGSEGV, Segmentation fault. 0x00000000005dda90 in check_typedef (type=0x6120736573756170) at src/gdb/gdbtypes.c:2388 2388 int instance_flags = TYPE_INSTANCE_FLAGS (type); ... This is a regression caused by a recent-ish refactoring of the code on 'whatis_exp', introduced by: commit c973d0aa4a2c737ab527ae44a617f1c357e07364 Date: Mon Aug 21 11:34:32 2017 +0100 Fix type casts losing typedefs and reimplement "whatis" typedef stripping Fix this by setting VAL to NULL in the "whatis TYPE" case, and skipping fetching the dynamic type if there's no value to fetch it from. New tests included. gdb/ChangeLog: 2018-01-22 Pedro Alves <palves@redhat.com> Sergio Durigan Junior <sergiodj@redhat.com> * typeprint.c (whatis_exp): Initialize "val" in the "whatis type" case. gdb/testsuite/ChangeLog: 2018-01-22 Pedro Alves <palves@redhat.com> Sergio Durigan Junior <sergiodj@redhat.com> * gdb.base/whatis.exp: Add tests for 'set print object on' + 'whatis <struct>' 'whatis <struct> *' and 'whatis <struct> &'.
Diffstat (limited to 'gdb/typeprint.c')
-rw-r--r--gdb/typeprint.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/gdb/typeprint.c b/gdb/typeprint.c
index 9a125076a1b..c098a3f4261 100644
--- a/gdb/typeprint.c
+++ b/gdb/typeprint.c
@@ -489,6 +489,10 @@ whatis_exp (const char *exp, int show)
check_typedef (type);
if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF)
type = TYPE_TARGET_TYPE (type);
+
+ /* If the expression is actually a type, then there's no
+ value to fetch the dynamic type from. */
+ val = NULL;
}
else
{
@@ -506,7 +510,7 @@ whatis_exp (const char *exp, int show)
}
get_user_print_options (&opts);
- if (opts.objectprint)
+ if (val != NULL && opts.objectprint)
{
if (((TYPE_CODE (type) == TYPE_CODE_PTR) || TYPE_IS_REFERENCE (type))
&& (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT))