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.
This commit is contained in:
Jan Kratochvil 2014-09-07 14:09:59 +02:00
parent 3f9d8762a4
commit c75bd3a239
7 changed files with 467 additions and 15 deletions

View file

@ -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",
_("<error reading variable: %s>"),
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;
}
gdbpy_convert_exception (except);
return EXT_LANG_BT_OK;
error:
return EXT_LANG_BT_ERROR;
return retval;
}
/* Helper function to loop over frame arguments provided by the