X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fpython%2Fpy-framefilter.c;h=67ad65a7cf441e2b7fb4f747e73f7ee0d950ada7;hb=112e8700a6fd2fed65ca70132c9cbed4132e8bd4;hp=e3336b14bb40e336c106f1171149f5c428734e44;hpb=492d29ea1c9a8b2c7d5193908119a4e27c045687;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c index e3336b14bb..67ad65a7cf 100644 --- a/gdb/python/py-framefilter.c +++ b/gdb/python/py-framefilter.c @@ -1,6 +1,6 @@ /* Python frame filters - Copyright (C) 2013-2015 Free Software Foundation, Inc. + Copyright (C) 2013-2016 Free Software Foundation, Inc. This file is part of GDB. @@ -43,15 +43,17 @@ enum mi_print_types NAME is a pass-through argument where the name of the symbol will be written. NAME is allocated in this function, but the caller is responsible for clean up. SYM is a pass-through argument where the - symbol will be written. In the case of the API returning a string, - this will be set to NULL. LANGUAGE is also a pass-through argument - denoting the language attributed to the Symbol. In the case of SYM - being NULL, this will be set to the current language. Returns - EXT_LANG_BT_ERROR on error with the appropriate Python exception set, and - EXT_LANG_BT_OK on success. */ + symbol will be written and SYM_BLOCK is a pass-through argument to + write the block where the symbol lies in. In the case of the API + returning a string, this will be set to NULL. LANGUAGE is also a + pass-through argument denoting the language attributed to the + Symbol. In the case of SYM being NULL, this will be set to the + current language. Returns EXT_LANG_BT_ERROR on error with the + appropriate Python exception set, and EXT_LANG_BT_OK on success. */ static enum ext_lang_bt_status -extract_sym (PyObject *obj, char **name, struct symbol **sym, +extract_sym (PyObject *obj, gdb::unique_xmalloc_ptr *name, + struct symbol **sym, struct block **sym_block, const struct language_defn **language) { PyObject *result = PyObject_CallMethod (obj, "symbol", NULL); @@ -75,12 +77,18 @@ extract_sym (PyObject *obj, char **name, struct symbol **sym, python_language. */ *language = python_language; *sym = NULL; + *sym_block = NULL; } else { /* This type checks 'result' during the conversion so we just call it unconditionally and check the return. */ *sym = symbol_object_to_symbol (result); + /* TODO: currently, we have no way to recover the block in which SYMBOL + was found, so we have no block to return. Trying to evaluate SYMBOL + will yield an incorrect value when it's located in a FRAME and + evaluated from another frame (as permitted in nested functions). */ + *sym_block = NULL; Py_DECREF (result); @@ -94,7 +102,7 @@ extract_sym (PyObject *obj, char **name, struct symbol **sym, /* Duplicate the symbol name, so the caller has consistency in garbage collection. */ - *name = xstrdup (SYMBOL_PRINT_NAME (*sym)); + name->reset (xstrdup (SYMBOL_PRINT_NAME (*sym))); /* If a symbol is specified attempt to determine the language from the symbol. If mode is not "auto", then the language @@ -204,15 +212,14 @@ py_print_type (struct ui_out *out, struct value *val) TRY { - struct type *type; struct ui_file *stb; struct cleanup *cleanup; stb = mem_fileopen (); cleanup = make_cleanup_ui_file_delete (stb); - type = check_typedef (value_type (val)); + check_typedef (value_type (val)); type_print (value_type (val), "", stb, -1); - ui_out_field_stream (out, "type", stb); + out->field_stream ("type", stb); do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) @@ -242,11 +249,6 @@ py_print_value (struct ui_out *out, struct value *val, const struct language_defn *language) { int should_print = 0; - int local_indent = (4 * indent); - - /* Never set an indent level for common_val_print if MI. */ - if (ui_out_is_mi_like_p (out)) - local_indent = 0; /* MI does not print certain values, differentiated by type, depending on what ARGS_TYPE indicates. Test type against option. @@ -288,7 +290,7 @@ py_print_value (struct ui_out *out, struct value *val, stb = mem_fileopen (); cleanup = make_cleanup_ui_file_delete (stb); common_val_print (val, stb, indent, opts, language); - ui_out_field_stream (out, "value", stb); + out->field_stream ("value", stb); do_cleanups (cleanup); } CATCH (except, RETURN_MASK_ALL) @@ -386,7 +388,7 @@ py_print_single_arg (struct ui_out *out, if the value is a frame argument. This is denoted in this function with PRINT_ARGS_FIELD which is flag from the caller to emit the ARGS field. */ - if (ui_out_is_mi_like_p (out)) + if (out->is_mi_like_p ()) { if (print_args_field || args_type != NO_VALUES) make_cleanup_ui_out_tuple_begin_end (out, NULL); @@ -418,19 +420,19 @@ py_print_single_arg (struct ui_out *out, { fputs_filtered ("@entry", stb); } - ui_out_field_stream (out, "name", stb); + out->field_stream ("name", stb); } else /* Otherwise, just output the name. */ - ui_out_field_string (out, "name", sym_name); + out->field_string ("name", sym_name); annotate_arg_name_end (); - if (! ui_out_is_mi_like_p (out)) - ui_out_text (out, "="); + if (! out->is_mi_like_p ()) + out->text ("="); if (print_args_field) - ui_out_field_int (out, "arg", 1); + out->field_int ("arg", 1); /* For MI print the type, but only for simple values. This seems weird, but this is how MI choose to format the various output @@ -441,37 +443,39 @@ py_print_single_arg (struct ui_out *out, { retval = EXT_LANG_BT_ERROR; do_cleanups (cleanups); - continue; } } - 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 "...". */ - if (! ui_out_is_mi_like_p (out) && args_type == NO_VALUES) - ui_out_field_string (out, "value", "..."); - else + if (retval != EXT_LANG_BT_ERROR) { - /* Otherwise, print the value for both MI and the CLI, except - for the case of MI_PRINT_NO_VALUES. */ - if (args_type != NO_VALUES) + 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 "...". */ + if (! out->is_mi_like_p () && args_type == NO_VALUES) + out->field_string ("value", "..."); + else { - if (val == NULL) + /* Otherwise, print the value for both MI and the CLI, except + for the case of MI_PRINT_NO_VALUES. */ + if (args_type != NO_VALUES) { - gdb_assert (fa != NULL && fa->error != NULL); - ui_out_field_fmt (out, "value", - _(""), - fa->error); + if (val == NULL) + { + gdb_assert (fa != NULL && fa->error != NULL); + out->field_fmt ("value", + _(""), + fa->error); + } + else if (py_print_value (out, val, opts, 0, args_type, language) + == EXT_LANG_BT_ERROR) + retval = EXT_LANG_BT_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); + do_cleanups (cleanups); + } } CATCH (except, RETURN_MASK_ERROR) { @@ -535,12 +539,13 @@ enumerate_args (PyObject *iter, while (item) { const struct language_defn *language; - char *sym_name; + gdb::unique_xmalloc_ptr sym_name; struct symbol *sym; + struct block *sym_block; struct value *val; enum ext_lang_bt_status success = EXT_LANG_BT_ERROR; - success = extract_sym (item, &sym_name, &sym, &language); + success = extract_sym (item, &sym_name, &sym, &sym_block, &language); if (success == EXT_LANG_BT_ERROR) { Py_DECREF (item); @@ -550,7 +555,6 @@ enumerate_args (PyObject *iter, success = extract_value (item, &val); if (success == EXT_LANG_BT_ERROR) { - xfree (sym_name); Py_DECREF (item); goto error; } @@ -558,12 +562,9 @@ enumerate_args (PyObject *iter, Py_DECREF (item); item = NULL; - if (sym && ui_out_is_mi_like_p (out) + if (sym && out->is_mi_like_p () && ! mi_should_print (sym, MI_PRINT_ARGS)) - { - xfree (sym_name); - continue; - } + continue; /* If the object did not provide a value, read it using read_frame_args and account for entry values, if any. */ @@ -577,7 +578,6 @@ enumerate_args (PyObject *iter, { PyErr_SetString (PyExc_RuntimeError, _("No symbol or value provided.")); - xfree (sym_name); goto error; } @@ -587,7 +587,6 @@ enumerate_args (PyObject *iter, } CATCH (except, RETURN_MASK_ALL) { - xfree (sym_name); gdbpy_convert_exception (except); goto error; } @@ -607,7 +606,6 @@ enumerate_args (PyObject *iter, { xfree (arg.error); xfree (entryarg.error); - xfree (sym_name); goto error; } } @@ -618,14 +616,13 @@ enumerate_args (PyObject *iter, { TRY { - ui_out_text (out, ", "); - ui_out_wrap_hint (out, " "); + out->text (", "); + out->wrap_hint (" "); } CATCH (except, RETURN_MASK_ALL) { xfree (arg.error); xfree (entryarg.error); - xfree (sym_name); gdbpy_convert_exception (except); goto error; } @@ -638,7 +635,6 @@ enumerate_args (PyObject *iter, { xfree (arg.error); xfree (entryarg.error); - xfree (sym_name); goto error; } } @@ -651,18 +647,13 @@ enumerate_args (PyObject *iter, /* If the object has provided a value, we just print that. */ if (val != NULL) { - if (py_print_single_arg (out, sym_name, NULL, val, &opts, + if (py_print_single_arg (out, sym_name.get (), NULL, val, &opts, args_type, print_args_field, language) == EXT_LANG_BT_ERROR) - { - xfree (sym_name); - goto error; - } + goto error; } } - xfree (sym_name); - /* Collect the next item from the iterator. If this is the last item, do not print the comma. */ @@ -671,7 +662,7 @@ enumerate_args (PyObject *iter, { TRY { - ui_out_text (out, ", "); + out->text (", "); } CATCH (except, RETURN_MASK_ALL) { @@ -732,24 +723,23 @@ enumerate_locals (PyObject *iter, while ((item = PyIter_Next (iter))) { const struct language_defn *language; - char *sym_name; + gdb::unique_xmalloc_ptr sym_name; struct value *val; enum ext_lang_bt_status success = EXT_LANG_BT_ERROR; struct symbol *sym; + struct block *sym_block; int local_indent = 8 + (8 * indent); struct cleanup *locals_cleanups; locals_cleanups = make_cleanup_py_decref (item); - success = extract_sym (item, &sym_name, &sym, &language); + success = extract_sym (item, &sym_name, &sym, &sym_block, &language); if (success == EXT_LANG_BT_ERROR) { do_cleanups (locals_cleanups); goto error; } - make_cleanup (xfree, sym_name); - success = extract_value (item, &val); if (success == EXT_LANG_BT_ERROR) { @@ -757,7 +747,7 @@ enumerate_locals (PyObject *iter, goto error; } - if (sym != NULL && ui_out_is_mi_like_p (out) + if (sym != NULL && out->is_mi_like_p () && ! mi_should_print (sym, MI_PRINT_LOCALS)) { do_cleanups (locals_cleanups); @@ -769,7 +759,7 @@ enumerate_locals (PyObject *iter, { TRY { - val = read_var_value (sym, frame); + val = read_var_value (sym, sym_block, frame); } CATCH (except, RETURN_MASK_ERROR) { @@ -783,23 +773,23 @@ enumerate_locals (PyObject *iter, /* With PRINT_NO_VALUES, MI does not emit a tuple normally as each output contains only one field. The exception is -stack-list-variables, which always provides a tuple. */ - if (ui_out_is_mi_like_p (out)) + if (out->is_mi_like_p ()) { if (print_args_field || args_type != NO_VALUES) make_cleanup_ui_out_tuple_begin_end (out, NULL); } TRY { - if (! ui_out_is_mi_like_p (out)) + if (! out->is_mi_like_p ()) { /* If the output is not MI we indent locals. */ - ui_out_spaces (out, local_indent); + out->spaces (local_indent); } - ui_out_field_string (out, "name", sym_name); + out->field_string ("name", sym_name.get ()); - if (! ui_out_is_mi_like_p (out)) - ui_out_text (out, " = "); + if (! out->is_mi_like_p ()) + out->text (" = "); } CATCH (except, RETURN_MASK_ERROR) { @@ -820,7 +810,7 @@ enumerate_locals (PyObject *iter, /* CLI always prints values for locals. MI uses the simple/no/all system. */ - if (! ui_out_is_mi_like_p (out)) + if (! out->is_mi_like_p ()) { int val_indent = (indent + 1) * 4; @@ -848,7 +838,7 @@ enumerate_locals (PyObject *iter, TRY { - ui_out_text (out, "\n"); + out->text ("\n"); } CATCH (except, RETURN_MASK_ERROR) { @@ -965,8 +955,8 @@ py_print_args (PyObject *filter, TRY { annotate_frame_args (); - if (! ui_out_is_mi_like_p (out)) - ui_out_text (out, " ("); + if (! out->is_mi_like_p ()) + out->text (" ("); } CATCH (except, RETURN_MASK_ALL) { @@ -982,8 +972,8 @@ py_print_args (PyObject *filter, TRY { - if (! ui_out_is_mi_like_p (out)) - ui_out_text (out, ")"); + if (! out->is_mi_like_p ()) + out->text (")"); } CATCH (except, RETURN_MASK_ALL) { @@ -1028,6 +1018,7 @@ py_print_frame (PyObject *filter, int flags, struct value_print_options opts; PyObject *py_inf_frame; int print_level, print_frame_info, print_args, print_locals; + gdb::unique_xmalloc_ptr function_to_free; /* Extract print settings from FLAGS. */ print_level = (flags & PRINT_LEVEL) ? 1 : 0; @@ -1086,7 +1077,7 @@ py_print_frame (PyObject *filter, int flags, { TRY { - ui_out_spaces (out, indent*4); + out->spaces (indent * 4); } CATCH (except, RETURN_MASK_ERROR) { @@ -1111,7 +1102,13 @@ py_print_frame (PyObject *filter, int flags, if (paddr != Py_None) { - address = PyLong_AsLong (paddr); + if (get_addr_from_python (paddr, &address) < 0) + { + Py_DECREF (paddr); + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } + has_addr = 1; } Py_DECREF (paddr); @@ -1136,14 +1133,14 @@ py_print_frame (PyObject *filter, int flags, architecture from the eliding frame. If that is the case, do not print 'level', but print spaces. */ if (*slot == frame) - ui_out_field_skip (out, "level"); + out->field_skip ("level"); else { *slot = frame; annotate_frame_begin (print_level ? level : 0, gdbarch, address); - ui_out_text (out, "#"); - ui_out_field_fmt_int (out, 2, ui_left, "level", + out->text ("#"); + out->field_fmt_int (2, ui_left, "level", level); } } @@ -1165,9 +1162,9 @@ py_print_frame (PyObject *filter, int flags, TRY { annotate_frame_address (); - ui_out_field_core_addr (out, "addr", gdbarch, address); + out->field_core_addr ("addr", gdbarch, address); annotate_frame_address_end (); - ui_out_text (out, " in "); + out->text (" in "); } CATCH (except, RETURN_MASK_ERROR) { @@ -1194,24 +1191,22 @@ py_print_frame (PyObject *filter, int flags, if (gdbpy_is_string (py_func)) { - char *function_to_free; + function_to_free = python_string_to_host_string (py_func); - function = function_to_free = - python_string_to_host_string (py_func); - - if (function == NULL) + if (function_to_free == NULL) { do_cleanups (cleanup_stack); return EXT_LANG_BT_ERROR; } - make_cleanup (xfree, function_to_free); + + function = function_to_free.get (); } else if (PyLong_Check (py_func)) { - CORE_ADDR addr = PyLong_AsUnsignedLongLong (py_func); + CORE_ADDR addr; struct bound_minimal_symbol msymbol; - if (PyErr_Occurred ()) + if (get_addr_from_python (py_func, &addr) < 0) { do_cleanups (cleanup_stack); return EXT_LANG_BT_ERROR; @@ -1234,9 +1229,9 @@ py_print_frame (PyObject *filter, int flags, { annotate_frame_function_name (); if (function == NULL) - ui_out_field_skip (out, "func"); + out->field_skip ("func"); else - ui_out_field_string (out, "func", function); + out->field_string ("func", function); } CATCH (except, RETURN_MASK_ERROR) { @@ -1291,7 +1286,8 @@ py_print_frame (PyObject *filter, int flags, if (py_fn != Py_None) { - char *filename = python_string_to_host_string (py_fn); + gdb::unique_xmalloc_ptr + filename (python_string_to_host_string (py_fn)); if (filename == NULL) { @@ -1299,13 +1295,12 @@ py_print_frame (PyObject *filter, int flags, return EXT_LANG_BT_ERROR; } - make_cleanup (xfree, filename); TRY { - ui_out_wrap_hint (out, " "); - ui_out_text (out, " at "); + out->wrap_hint (" "); + out->text (" at "); annotate_frame_source_file (); - ui_out_field_string (out, "file", filename); + out->field_string ("file", filename.get ()); annotate_frame_source_file_end (); } CATCH (except, RETURN_MASK_ERROR) @@ -1335,11 +1330,17 @@ py_print_frame (PyObject *filter, int flags, if (py_line != Py_None) { line = PyLong_AsLong (py_line); + if (PyErr_Occurred ()) + { + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } + TRY { - ui_out_text (out, ":"); + out->text (":"); annotate_frame_source_line (); - ui_out_field_int (out, "line", line); + out->field_int ("line", line); } CATCH (except, RETURN_MASK_ERROR) { @@ -1355,12 +1356,12 @@ py_print_frame (PyObject *filter, int flags, /* For MI we need to deal with the "children" list population of elided frames, so if MI output detected do not send newline. */ - if (! ui_out_is_mi_like_p (out)) + if (! out->is_mi_like_p ()) { TRY { annotate_frame_end (); - ui_out_text (out, "\n"); + out->text ("\n"); } CATCH (except, RETURN_MASK_ERROR) { @@ -1400,7 +1401,7 @@ py_print_frame (PyObject *filter, int flags, make_cleanup_ui_out_list_begin_end (out, "children"); - if (! ui_out_is_mi_like_p (out)) + if (! out->is_mi_like_p ()) indent++; while ((item = PyIter_Next (elided)))