X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fpython%2Fpy-framefilter.c;h=67ad65a7cf441e2b7fb4f747e73f7ee0d950ada7;hb=112e8700a6fd2fed65ca70132c9cbed4132e8bd4;hp=9db83c702191d2febcfb27261d5eec9684b8101e;hpb=efd66ac6698323d9523a4dce352008c4c835812e;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c index 9db83c7021..67ad65a7cf 100644 --- a/gdb/python/py-framefilter.c +++ b/gdb/python/py-framefilter.c @@ -1,6 +1,6 @@ /* Python frame filters - Copyright (C) 2013-2014 Free Software Foundation, Inc. + Copyright (C) 2013-2016 Free Software Foundation, Inc. This file is part of GDB. @@ -21,7 +21,6 @@ #include "objfiles.h" #include "symtab.h" #include "language.h" -#include "exceptions.h" #include "arch-utils.h" #include "python.h" #include "ui-out.h" @@ -44,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); @@ -76,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); @@ -95,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 @@ -202,26 +209,25 @@ mi_should_print (struct symbol *sym, enum mi_print_types type) static enum ext_lang_bt_status py_print_type (struct ui_out *out, struct value *val) { - volatile struct gdb_exception except; - TRY_CATCH (except, RETURN_MASK_ALL) + 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); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ALL) { gdbpy_convert_exception (except); return EXT_LANG_BT_ERROR; } + END_CATCH return EXT_LANG_BT_OK; } @@ -243,12 +249,6 @@ py_print_value (struct ui_out *out, struct value *val, const struct language_defn *language) { int should_print = 0; - volatile struct gdb_exception except; - 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. @@ -258,15 +258,16 @@ py_print_value (struct ui_out *out, struct value *val, { struct type *type = NULL; - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { type = check_typedef (value_type (val)); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ALL) { gdbpy_convert_exception (except); return EXT_LANG_BT_ERROR; } + END_CATCH if (args_type == MI_PRINT_ALL_VALUES) should_print = 1; @@ -281,7 +282,7 @@ py_print_value (struct ui_out *out, struct value *val, if (should_print) { - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { struct ui_file *stb; struct cleanup *cleanup; @@ -289,14 +290,15 @@ 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); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ALL) { gdbpy_convert_exception (except); return EXT_LANG_BT_ERROR; } + END_CATCH } return EXT_LANG_BT_OK; @@ -364,17 +366,19 @@ py_print_single_arg (struct ui_out *out, const struct language_defn *language) { 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; } else val = fv; - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { struct cleanup *cleanups = make_cleanup (null_cleanup, NULL); @@ -384,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); @@ -416,65 +420,70 @@ 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 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; } } - 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 (py_print_value (out, val, opts, 0, args_type, language) - == 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) { - do_cleanups (cleanups); - goto 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; } } - } - do_cleanups (cleanups); + do_cleanups (cleanups); + } } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ERROR) { gdbpy_convert_exception (except); - goto error; } + END_CATCH - return EXT_LANG_BT_OK; - - error: - return EXT_LANG_BT_ERROR; + return retval; } /* Helper function to loop over frame arguments provided by the @@ -497,7 +506,6 @@ enumerate_args (PyObject *iter, { PyObject *item; struct value_print_options opts; - volatile struct gdb_exception except; get_user_print_options (&opts); @@ -509,15 +517,16 @@ enumerate_args (PyObject *iter, opts.deref_ref = 1; - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { annotate_frame_args (); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ALL) { gdbpy_convert_exception (except); goto error; } + END_CATCH /* Collect the first argument outside of the loop, so output of commas in the argument output is correct. At the end of the @@ -530,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); @@ -545,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; } @@ -553,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. */ @@ -572,20 +578,19 @@ enumerate_args (PyObject *iter, { PyErr_SetString (PyExc_RuntimeError, _("No symbol or value provided.")); - xfree (sym_name); goto error; } - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { read_frame_arg (sym, frame, &arg, &entryarg); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ALL) { - xfree (sym_name); gdbpy_convert_exception (except); goto error; } + END_CATCH /* The object has not provided a value, so this is a frame argument to be read by GDB. In this case we have to @@ -601,7 +606,6 @@ enumerate_args (PyObject *iter, { xfree (arg.error); xfree (entryarg.error); - xfree (sym_name); goto error; } } @@ -610,19 +614,19 @@ enumerate_args (PyObject *iter, { if (arg.entry_kind != print_entry_values_only) { - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { - ui_out_text (out, ", "); - ui_out_wrap_hint (out, " "); + out->text (", "); + out->wrap_hint (" "); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ALL) { xfree (arg.error); xfree (entryarg.error); - xfree (sym_name); gdbpy_convert_exception (except); goto error; } + END_CATCH } if (py_print_single_arg (out, NULL, &entryarg, NULL, &opts, @@ -631,7 +635,6 @@ enumerate_args (PyObject *iter, { xfree (arg.error); xfree (entryarg.error); - xfree (sym_name); goto error; } } @@ -644,48 +647,45 @@ 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. */ item = PyIter_Next (iter); if (item != NULL) { - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { - ui_out_text (out, ", "); + out->text (", "); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ALL) { Py_DECREF (item); gdbpy_convert_exception (except); goto error; } + END_CATCH } else if (PyErr_Occurred ()) goto error; - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { annotate_arg_end (); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ALL) { Py_DECREF (item); gdbpy_convert_exception (except); goto error; } + END_CATCH } return EXT_LANG_BT_OK; @@ -723,25 +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; - volatile struct gdb_exception except; + 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) { @@ -749,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); @@ -759,45 +757,47 @@ enumerate_locals (PyObject *iter, /* If the object did not provide a value, read it. */ if (val == NULL) { - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { - val = read_var_value (sym, frame); + val = read_var_value (sym, sym_block, frame); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ERROR) { gdbpy_convert_exception (except); do_cleanups (locals_cleanups); goto error; } + END_CATCH } /* 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_CATCH (except, RETURN_MASK_ALL) + 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 (" = "); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ERROR) { gdbpy_convert_exception (except); do_cleanups (locals_cleanups); goto error; } + END_CATCH if (args_type == MI_PRINT_SIMPLE_VALUES) { @@ -810,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; @@ -836,15 +836,16 @@ enumerate_locals (PyObject *iter, do_cleanups (locals_cleanups); - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { - ui_out_text (out, "\n"); + out->text ("\n"); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ERROR) { gdbpy_convert_exception (except); goto error; } + END_CATCH } if (item == NULL && PyErr_Occurred ()) @@ -945,40 +946,41 @@ py_print_args (PyObject *filter, { PyObject *args_iter = get_py_iter_from_func (filter, "frame_args"); struct cleanup *old_chain = make_cleanup_py_xdecref (args_iter); - volatile struct gdb_exception except; if (args_iter == NULL) goto args_error; make_cleanup_ui_out_list_begin_end (out, "args"); - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { annotate_frame_args (); - if (! ui_out_is_mi_like_p (out)) - ui_out_text (out, " ("); + if (! out->is_mi_like_p ()) + out->text (" ("); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ALL) { gdbpy_convert_exception (except); goto args_error; } + END_CATCH if (args_iter != Py_None) if (enumerate_args (args_iter, out, args_type, 0, frame) == EXT_LANG_BT_ERROR) goto args_error; - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { - if (! ui_out_is_mi_like_p (out)) - ui_out_text (out, ")"); + if (! out->is_mi_like_p ()) + out->text (")"); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ALL) { gdbpy_convert_exception (except); goto args_error; } + END_CATCH do_cleanups (old_chain); return EXT_LANG_BT_OK; @@ -1001,7 +1003,7 @@ py_print_args (PyObject *filter, If a frame level has been printed, do not print it again (in the case of elided frames). Returns EXT_LANG_BT_ERROR on error, with any GDB exceptions converted to a Python exception, or EXT_LANG_BT_COMPLETED - on success. */ + on success. It can also throw an exception RETURN_QUIT. */ static enum ext_lang_bt_status py_print_frame (PyObject *filter, int flags, @@ -1012,11 +1014,11 @@ py_print_frame (PyObject *filter, int flags, CORE_ADDR address = 0; struct gdbarch *gdbarch = NULL; struct frame_info *frame = NULL; - struct cleanup *cleanup_stack = make_cleanup (null_cleanup, NULL); + struct cleanup *cleanup_stack; struct value_print_options opts; - PyObject *py_inf_frame, *elided; + PyObject *py_inf_frame; int print_level, print_frame_info, print_args, print_locals; - volatile struct gdb_exception except; + gdb::unique_xmalloc_ptr function_to_free; /* Extract print settings from FLAGS. */ print_level = (flags & PRINT_LEVEL) ? 1 : 0; @@ -1031,39 +1033,37 @@ py_print_frame (PyObject *filter, int flags, read them if they returned filter object requires us to do so. */ py_inf_frame = PyObject_CallMethod (filter, "inferior_frame", NULL); if (py_inf_frame == NULL) - goto error; + return EXT_LANG_BT_ERROR; frame = frame_object_to_frame_info (py_inf_frame);; Py_DECREF (py_inf_frame); if (frame == NULL) - goto error; + return EXT_LANG_BT_ERROR; - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { gdbarch = get_frame_arch (frame); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ERROR) { gdbpy_convert_exception (except); - goto error; + return EXT_LANG_BT_ERROR; } - + END_CATCH /* stack-list-variables. */ if (print_locals && print_args && ! print_frame_info) { if (py_mi_print_variables (filter, out, &opts, args_type, frame) == EXT_LANG_BT_ERROR) - goto error; - else - { - do_cleanups (cleanup_stack); - return EXT_LANG_BT_COMPLETED; - } + return EXT_LANG_BT_ERROR; + return EXT_LANG_BT_COMPLETED; } + cleanup_stack = make_cleanup (null_cleanup, NULL); + /* -stack-list-locals does not require a wrapping frame attribute. */ if (print_frame_info || (print_args && ! print_locals)) @@ -1075,15 +1075,17 @@ py_print_frame (PyObject *filter, int flags, and are printed with indention. */ if (indent > 0) { - TRY_CATCH (except, RETURN_MASK_ALL) - { - ui_out_spaces (out, indent*4); - } - if (except.reason < 0) - { - gdbpy_convert_exception (except); - goto error; - } + TRY + { + out->spaces (indent * 4); + } + CATCH (except, RETURN_MASK_ERROR) + { + gdbpy_convert_exception (except); + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } + END_CATCH } /* The address is required for frame annotations, and also for @@ -1091,17 +1093,25 @@ py_print_frame (PyObject *filter, int flags, if (PyObject_HasAttrString (filter, "address")) { PyObject *paddr = PyObject_CallMethod (filter, "address", NULL); - if (paddr != NULL) + + if (paddr == NULL) { - if (paddr != Py_None) + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } + + if (paddr != Py_None) + { + if (get_addr_from_python (paddr, &address) < 0) { - address = PyLong_AsLong (paddr); - has_addr = 1; + Py_DECREF (paddr); + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; } - Py_DECREF (paddr); + + has_addr = 1; } - else - goto error; + Py_DECREF (paddr); } } @@ -1111,11 +1121,10 @@ py_print_frame (PyObject *filter, int flags, { struct frame_info **slot; int level; - volatile struct gdb_exception except; slot = (struct frame_info **) htab_find_slot (levels_printed, frame, INSERT); - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { level = frame_relative_level (frame); @@ -1124,22 +1133,24 @@ 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); } } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ERROR) { gdbpy_convert_exception (except); - goto error; + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; } + END_CATCH } if (print_frame_info) @@ -1148,83 +1159,89 @@ py_print_frame (PyObject *filter, int flags, print nothing. */ if (opts.addressprint && has_addr) { - TRY_CATCH (except, RETURN_MASK_ALL) + 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 "); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ERROR) { gdbpy_convert_exception (except); - goto error; + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; } + END_CATCH } /* Print frame function name. */ if (PyObject_HasAttrString (filter, "function")) { PyObject *py_func = PyObject_CallMethod (filter, "function", NULL); + struct cleanup *py_func_cleanup; + const char *function = NULL; - if (py_func != NULL) + if (py_func == NULL) { - const char *function = NULL; - - if (gdbpy_is_string (py_func)) - { - char *function_to_free = NULL; + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } + py_func_cleanup = make_cleanup_py_decref (py_func); - function = function_to_free = - python_string_to_host_string (py_func); + if (gdbpy_is_string (py_func)) + { + function_to_free = python_string_to_host_string (py_func); - if (function == NULL) - { - Py_DECREF (py_func); - goto error; - } - make_cleanup (xfree, function_to_free); - } - else if (PyLong_Check (py_func)) + if (function_to_free == NULL) { - CORE_ADDR addr = PyLong_AsUnsignedLongLong (py_func); - struct bound_minimal_symbol msymbol; + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } - if (PyErr_Occurred ()) - goto error; + function = function_to_free.get (); + } + else if (PyLong_Check (py_func)) + { + CORE_ADDR addr; + struct bound_minimal_symbol msymbol; - msymbol = lookup_minimal_symbol_by_pc (addr); - if (msymbol.minsym != NULL) - function = MSYMBOL_PRINT_NAME (msymbol.minsym); - } - else if (py_func != Py_None) + if (get_addr_from_python (py_func, &addr) < 0) { - PyErr_SetString (PyExc_RuntimeError, - _("FrameDecorator.function: expecting a " \ - "String, integer or None.")); - Py_DECREF (py_func); - goto error; + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; } + msymbol = lookup_minimal_symbol_by_pc (addr); + if (msymbol.minsym != NULL) + function = MSYMBOL_PRINT_NAME (msymbol.minsym); + } + else if (py_func != Py_None) + { + PyErr_SetString (PyExc_RuntimeError, + _("FrameDecorator.function: expecting a " \ + "String, integer or None.")); + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } - TRY_CATCH (except, RETURN_MASK_ALL) - { - annotate_frame_function_name (); - if (function == NULL) - ui_out_field_skip (out, "func"); - else - ui_out_field_string (out, "func", function); - } - if (except.reason < 0) - { - Py_DECREF (py_func); - gdbpy_convert_exception (except); - goto error; - } - Py_DECREF (py_func); + TRY + { + annotate_frame_function_name (); + if (function == NULL) + out->field_skip ("func"); + else + out->field_string ("func", function); } - else - goto error; + CATCH (except, RETURN_MASK_ERROR) + { + gdbpy_convert_exception (except); + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } + END_CATCH + + do_cleanups (py_func_cleanup); } } @@ -1234,154 +1251,187 @@ py_print_frame (PyObject *filter, int flags, if (print_args) { if (py_print_args (filter, out, args_type, frame) == EXT_LANG_BT_ERROR) - goto error; + { + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } } /* File name/source/line number information. */ if (print_frame_info) { - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { annotate_frame_source_begin (); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ERROR) { gdbpy_convert_exception (except); - goto error; + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; } + END_CATCH if (PyObject_HasAttrString (filter, "filename")) { - PyObject *py_fn = PyObject_CallMethod (filter, "filename", - NULL); - if (py_fn != NULL) + PyObject *py_fn = PyObject_CallMethod (filter, "filename", NULL); + struct cleanup *py_fn_cleanup; + + if (py_fn == NULL) { - if (py_fn != Py_None) - { - char *filename = python_string_to_host_string (py_fn); + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } + py_fn_cleanup = make_cleanup_py_decref (py_fn); - if (filename == NULL) - { - Py_DECREF (py_fn); - goto error; - } + if (py_fn != Py_None) + { + gdb::unique_xmalloc_ptr + filename (python_string_to_host_string (py_fn)); - make_cleanup (xfree, filename); - TRY_CATCH (except, RETURN_MASK_ALL) - { - ui_out_wrap_hint (out, " "); - ui_out_text (out, " at "); - annotate_frame_source_file (); - ui_out_field_string (out, "file", filename); - annotate_frame_source_file_end (); - } - if (except.reason < 0) - { - Py_DECREF (py_fn); - gdbpy_convert_exception (except); - goto error; - } + if (filename == NULL) + { + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; } - Py_DECREF (py_fn); + + TRY + { + out->wrap_hint (" "); + out->text (" at "); + annotate_frame_source_file (); + out->field_string ("file", filename.get ()); + annotate_frame_source_file_end (); + } + CATCH (except, RETURN_MASK_ERROR) + { + gdbpy_convert_exception (except); + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } + END_CATCH } - else - goto error; + do_cleanups (py_fn_cleanup); } if (PyObject_HasAttrString (filter, "line")) { PyObject *py_line = PyObject_CallMethod (filter, "line", NULL); + struct cleanup *py_line_cleanup; int line; - if (py_line != NULL) + if (py_line == NULL) + { + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } + py_line_cleanup = make_cleanup_py_decref (py_line); + + if (py_line != Py_None) { - if (py_line != Py_None) + line = PyLong_AsLong (py_line); + if (PyErr_Occurred ()) { - line = PyLong_AsLong (py_line); - TRY_CATCH (except, RETURN_MASK_ALL) - { - ui_out_text (out, ":"); - annotate_frame_source_line (); - ui_out_field_int (out, "line", line); - } - if (except.reason < 0) - { - Py_DECREF (py_line); - gdbpy_convert_exception (except); - goto error; - } + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } + + TRY + { + out->text (":"); + annotate_frame_source_line (); + out->field_int ("line", line); } - Py_DECREF (py_line); + CATCH (except, RETURN_MASK_ERROR) + { + gdbpy_convert_exception (except); + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } + END_CATCH } - else - goto error; + do_cleanups (py_line_cleanup); } } /* 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_CATCH (except, RETURN_MASK_ALL) + TRY { annotate_frame_end (); - ui_out_text (out, "\n"); + out->text ("\n"); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ERROR) { gdbpy_convert_exception (except); - goto error; + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; } + END_CATCH } if (print_locals) { if (py_print_locals (filter, out, args_type, indent, frame) == EXT_LANG_BT_ERROR) - goto error; + { + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } } - /* Finally recursively print elided frames, if any. */ - elided = get_py_iter_from_func (filter, "elided"); - if (elided == NULL) - goto error; + { + PyObject *elided; + struct cleanup *elided_cleanup; - make_cleanup_py_decref (elided); - if (elided != Py_None) - { - PyObject *item; + /* Finally recursively print elided frames, if any. */ + elided = get_py_iter_from_func (filter, "elided"); + if (elided == NULL) + { + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } + elided_cleanup = make_cleanup_py_decref (elided); - make_cleanup_ui_out_list_begin_end (out, "children"); + if (elided != Py_None) + { + PyObject *item; - if (! ui_out_is_mi_like_p (out)) - indent++; + make_cleanup_ui_out_list_begin_end (out, "children"); - while ((item = PyIter_Next (elided))) - { - enum ext_lang_bt_status success = py_print_frame (item, flags, - args_type, out, - indent, - levels_printed); + if (! out->is_mi_like_p ()) + indent++; - if (success == EXT_LANG_BT_ERROR) - { - Py_DECREF (item); - goto error; - } + while ((item = PyIter_Next (elided))) + { + struct cleanup *item_cleanup = make_cleanup_py_decref (item); - Py_DECREF (item); - } - if (item == NULL && PyErr_Occurred ()) - goto error; - } + enum ext_lang_bt_status success = py_print_frame (item, flags, + args_type, out, + indent, + levels_printed); + do_cleanups (item_cleanup); - do_cleanups (cleanup_stack); - return EXT_LANG_BT_COMPLETED; + if (success == EXT_LANG_BT_ERROR) + { + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } + } + if (item == NULL && PyErr_Occurred ()) + { + do_cleanups (cleanup_stack); + return EXT_LANG_BT_ERROR; + } + } + do_cleanups (elided_cleanup); + } - error: do_cleanups (cleanup_stack); - return EXT_LANG_BT_ERROR; + return EXT_LANG_BT_COMPLETED; } /* Helper function to initiate frame filter invocation at starting @@ -1472,22 +1522,22 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang, struct cleanup *cleanups; enum ext_lang_bt_status success = EXT_LANG_BT_ERROR; PyObject *iterable; - volatile struct gdb_exception except; PyObject *item; htab_t levels_printed; if (!gdb_python_initialized) return EXT_LANG_BT_NO_FILTERS; - TRY_CATCH (except, RETURN_MASK_ALL) + TRY { gdbarch = get_frame_arch (frame); } - if (except.reason < 0) + CATCH (except, RETURN_MASK_ALL) { /* Let gdb try to print the stack trace. */ return EXT_LANG_BT_NO_FILTERS; } + END_CATCH cleanups = ensure_python_env (gdbarch, current_language); @@ -1531,15 +1581,17 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang, while ((item = PyIter_Next (iterable))) { + struct cleanup *item_cleanup = make_cleanup_py_decref (item); + success = py_print_frame (item, flags, args_type, out, 0, levels_printed); + do_cleanups (item_cleanup); + /* Do not exit on error printing a single frame. Print the error and continue with other frames. */ if (success == EXT_LANG_BT_ERROR) gdbpy_print_stack (); - - Py_DECREF (item); } if (item == NULL && PyErr_Occurred ())