From c75bd3a23915c3122070a95e1974e323543ffbe4 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Sun, 7 Sep 2014 14:09:59 +0200 Subject: Fix crash on Python frame filters with unreadable arg https://bugzilla.redhat.com/show_bug.cgi?id=1126177 ERROR: AddressSanitizer: SEGV on unknown address 0x000000000050 (pc 0x000000992bef sp 0x7ffff9039530 bp 0x7ffff9039540 T0) #0 0x992bee in value_type .../gdb/value.c:925 #1 0x87c951 in py_print_single_arg python/py-framefilter.c:445 #2 0x87cfae in enumerate_args python/py-framefilter.c:596 #3 0x87e0b0 in py_print_args python/py-framefilter.c:968 It crashes because frame_arg::val is documented it may contain NULL (frame_arg::error is then non-NULL) but the code does not handle it. Another bug is that py_print_single_arg() calls goto out of its TRY_CATCH which messes up GDB cleanup chain crashing GDB later. It is probably 7.7 regression (I have not verified it) due to the introduction of Python frame filters. gdb/ChangeLog PR python/17355 * python/py-framefilter.c (py_print_single_arg): Handle NULL FA->VAL. Fix goto out of TRY_CATCH. gdb/testsuite/ChangeLog PR python/17355 * gdb.python/amd64-py-framefilter-invalidarg.S: New file. * gdb.python/py-framefilter-invalidarg-gdb.py.in: New file. * gdb.python/py-framefilter-invalidarg.exp: New file. * gdb.python/py-framefilter-invalidarg.py: New file. --- gdb/python/py-framefilter.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'gdb/python') diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c index 9db83c7..d53282f 100644 --- a/gdb/python/py-framefilter.c +++ b/gdb/python/py-framefilter.c @@ -365,9 +365,12 @@ py_print_single_arg (struct ui_out *out, { struct value *val; volatile struct gdb_exception except; + enum ext_lang_bt_status retval = EXT_LANG_BT_OK; if (fa != NULL) { + if (fa->val == NULL && fa->error == NULL) + return EXT_LANG_BT_OK; language = language_def (SYMBOL_LANGUAGE (fa->sym)); val = fa->val; } @@ -433,16 +436,18 @@ py_print_single_arg (struct ui_out *out, /* For MI print the type, but only for simple values. This seems weird, but this is how MI choose to format the various output types. */ - if (args_type == MI_PRINT_SIMPLE_VALUES) + if (args_type == MI_PRINT_SIMPLE_VALUES && val != NULL) { if (py_print_type (out, val) == EXT_LANG_BT_ERROR) { + retval = EXT_LANG_BT_ERROR; do_cleanups (cleanups); - goto error; + continue; } } - annotate_arg_value (value_type (val)); + if (val != NULL) + annotate_arg_value (value_type (val)); /* If the output is to the CLI, and the user option "set print frame-arguments" is set to none, just output "...". */ @@ -454,27 +459,25 @@ py_print_single_arg (struct ui_out *out, for the case of MI_PRINT_NO_VALUES. */ if (args_type != NO_VALUES) { - if (py_print_value (out, val, opts, 0, args_type, language) - == EXT_LANG_BT_ERROR) + if (val == NULL) { - do_cleanups (cleanups); - goto error; + gdb_assert (fa != NULL && fa->error != NULL); + ui_out_field_fmt (out, "value", + _(""), + fa->error); } + else if (py_print_value (out, val, opts, 0, args_type, language) + == EXT_LANG_BT_ERROR) + retval = EXT_LANG_BT_ERROR; } } do_cleanups (cleanups); } if (except.reason < 0) - { - gdbpy_convert_exception (except); - goto error; - } - - return EXT_LANG_BT_OK; + gdbpy_convert_exception (except); - error: - return EXT_LANG_BT_ERROR; + return retval; } /* Helper function to loop over frame arguments provided by the -- cgit v1.1