X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fpython%2Fpy-framefilter.c;h=ecd633ab6950d6d2fc52fe307d53ff941897540d;hb=1ba7cdcd931ddf672e4a8a6483593f9b94e55965;hp=698fd87f4b50399946d466fe5aa15b7d1918ab92;hpb=76c939acfd21928957b45816bf78935363438b0a;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c index 698fd87f4b..ecd633ab69 100644 --- a/gdb/python/py-framefilter.c +++ b/gdb/python/py-framefilter.c @@ -1,6 +1,6 @@ /* Python frame filters - Copyright (C) 2013-2018 Free Software Foundation, Inc. + Copyright (C) 2013-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -25,13 +25,14 @@ #include "python.h" #include "ui-out.h" #include "valprint.h" +#include "stack.h" +#include "source.h" #include "annotate.h" #include "hashtab.h" #include "demangle.h" #include "mi/mi-cmds.h" #include "python-internal.h" -#include "py-ref.h" -#include "common/gdb_optional.h" +#include "gdbsupport/gdb_optional.h" enum mi_print_types { @@ -55,7 +56,7 @@ enum mi_print_types static enum ext_lang_bt_status extract_sym (PyObject *obj, gdb::unique_xmalloc_ptr *name, - struct symbol **sym, struct block **sym_block, + struct symbol **sym, const struct block **sym_block, const struct language_defn **language) { gdbpy_ref<> result (PyObject_CallMethod (obj, "symbol", NULL)); @@ -368,11 +369,10 @@ py_print_single_arg (struct ui_out *out, annotate_arg_name_end (); - if (! out->is_mi_like_p ()) - out->text ("="); + out->text ("="); if (print_args_field) - out->field_int ("arg", 1); + out->field_signed ("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 @@ -398,7 +398,7 @@ py_print_single_arg (struct ui_out *out, gdb_assert (fa != NULL && fa->error != NULL); out->field_fmt ("value", _(""), - fa->error); + fa->error.get ()); } else py_print_value (out, val, opts, 0, args_type, language); @@ -451,7 +451,7 @@ enumerate_args (PyObject *iter, const struct language_defn *language; gdb::unique_xmalloc_ptr sym_name; struct symbol *sym; - struct block *sym_block; + const struct block *sym_block; struct value *val; enum ext_lang_bt_status success = EXT_LANG_BT_ERROR; @@ -483,10 +483,8 @@ enumerate_args (PyObject *iter, return EXT_LANG_BT_ERROR; } - read_frame_arg (sym, frame, &arg, &entryarg); - - gdb::unique_xmalloc_ptr arg_holder (arg.error); - gdb::unique_xmalloc_ptr entry_holder (entryarg.error); + read_frame_arg (user_frame_print_options, + sym, frame, &arg, &entryarg); /* The object has not provided a value, so this is a frame argument to be read by GDB. In this case we have to @@ -569,7 +567,7 @@ enumerate_locals (PyObject *iter, struct value *val; enum ext_lang_bt_status success = EXT_LANG_BT_ERROR; struct symbol *sym; - struct block *sym_block; + const struct block *sym_block; int local_indent = 8 + (8 * indent); gdb::optional tuple; @@ -602,16 +600,11 @@ enumerate_locals (PyObject *iter, if (print_args_field || args_type != NO_VALUES) tuple.emplace (out, nullptr); } - if (! out->is_mi_like_p ()) - { - /* If the output is not MI we indent locals. */ - out->spaces (local_indent); - } + /* If the output is not MI we indent locals. */ + out->spaces (local_indent); out->field_string ("name", sym_name.get ()); - - if (! out->is_mi_like_p ()) - out->text (" = "); + out->text (" = "); if (args_type == MI_PRINT_SIMPLE_VALUES) py_print_type (out, val); @@ -717,16 +710,26 @@ py_print_args (PyObject *filter, out->wrap_hint (" "); annotate_frame_args (); - if (! out->is_mi_like_p ()) - out->text (" ("); + out->text (" ("); - if (args_iter != Py_None - && (enumerate_args (args_iter.get (), out, args_type, 0, frame) - == EXT_LANG_BT_ERROR)) + if (args_type == CLI_PRESENCE) + { + if (args_iter != Py_None) + { + gdbpy_ref<> item (PyIter_Next (args_iter.get ())); + + if (item != NULL) + out->text ("..."); + else if (PyErr_Occurred ()) + return EXT_LANG_BT_ERROR; + } + } + else if (args_iter != Py_None + && (enumerate_args (args_iter.get (), out, args_type, 0, frame) + == EXT_LANG_BT_ERROR)) return EXT_LANG_BT_ERROR; - if (! out->is_mi_like_p ()) - out->text (")"); + out->text (")"); return EXT_LANG_BT_OK; } @@ -756,7 +759,16 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, struct gdbarch *gdbarch = NULL; struct frame_info *frame = NULL; struct value_print_options opts; + int print_level, print_frame_info, print_args, print_locals; + /* Note that the below default in non-mi mode is the same as the + default value for the backtrace command (see the call to print_frame_info + in backtrace_command_1). + Having the same default ensures that 'bt' and 'bt no-filters' + have the same behaviour when some filters exist but do not apply + to a frame. */ + enum print_what print_what + = out->is_mi_like_p () ? LOC_AND_ADDRESS : LOCATION; gdb::unique_xmalloc_ptr function_to_free; /* Extract print settings from FLAGS. */ @@ -766,6 +778,17 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, print_locals = (flags & PRINT_LOCALS) ? 1 : 0; get_user_print_options (&opts); + if (print_frame_info) + { + gdb::optional user_frame_info_print_what; + + get_user_print_what_frame_info (&user_frame_info_print_what); + if (!out->is_mi_like_p () && user_frame_info_print_what.has_value ()) + { + /* Use the specific frame information desired by the user. */ + print_what = *user_frame_info_print_what; + } + } /* Get the underlying frame. This is needed to determine GDB architecture, and also, in the cases of frame variables/arguments to @@ -779,6 +802,8 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, if (frame == NULL) return EXT_LANG_BT_ERROR; + symtab_and_line sal = find_frame_sal (frame); + gdbarch = get_frame_arch (frame); /* stack-list-variables. */ @@ -823,9 +848,19 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, } } + /* For MI, each piece is controlled individually. */ + bool location_print = (print_frame_info + && !out->is_mi_like_p () + && (print_what == LOCATION + || print_what == SRC_AND_LOC + || print_what == LOC_AND_ADDRESS + || print_what == SHORT_LOCATION)); + /* Print frame level. MI does not require the level if locals/variables only are being printed. */ - if ((print_frame_info || print_args) && print_level) + if (print_level + && (location_print + || (out->is_mi_like_p () && (print_frame_info || print_args)))) { struct frame_info **slot; int level; @@ -847,21 +882,27 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, annotate_frame_begin (print_level ? level : 0, gdbarch, address); out->text ("#"); - out->field_fmt_int (2, ui_left, "level", - level); + out->field_fmt_signed (2, ui_left, "level", level); } } - if (print_frame_info) + if (location_print || (out->is_mi_like_p () && print_frame_info)) { /* Print address to the address field. If an address is not provided, print nothing. */ if (opts.addressprint && has_addr) { - annotate_frame_address (); - out->field_core_addr ("addr", gdbarch, address); - annotate_frame_address_end (); - out->text (" in "); + if (!sal.symtab + || frame_show_address (frame, sal) + || print_what == LOC_AND_ADDRESS) + { + annotate_frame_address (); + out->field_core_addr ("addr", gdbarch, address); + if (get_frame_pc_masked (frame)) + out->field_string ("pac", " [PAC]"); + annotate_frame_address_end (); + out->text (" in "); + } } /* Print frame function name. */ @@ -906,21 +947,24 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, if (function == NULL) out->field_skip ("func"); else - out->field_string ("func", function); + out->field_string ("func", function, ui_out_style_kind::FUNCTION); } } /* Frame arguments. Check the result, and error if something went wrong. */ - if (print_args) + if (print_args && (location_print || out->is_mi_like_p ())) { if (py_print_args (filter, out, args_type, frame) == EXT_LANG_BT_ERROR) return EXT_LANG_BT_ERROR; } /* File name/source/line number information. */ - if (print_frame_info) + bool print_location_source + = ((location_print && print_what != SHORT_LOCATION) + || (out->is_mi_like_p () && print_frame_info)); + if (print_location_source) { annotate_frame_source_begin (); @@ -942,7 +986,8 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, out->wrap_hint (" "); out->text (" at "); annotate_frame_source_file (); - out->field_string ("file", filename.get ()); + out->field_string ("file", filename.get (), + ui_out_style_kind::FILE); annotate_frame_source_file_end (); } } @@ -963,9 +1008,22 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, out->text (":"); annotate_frame_source_line (); - out->field_int ("line", line); + out->field_signed ("line", line); } } + if (out->is_mi_like_p ()) + out->field_string ("arch", + (gdbarch_bfd_arch_info (gdbarch))->printable_name); + } + + bool source_print + = (! out->is_mi_like_p () + && (print_what == SRC_LINE || print_what == SRC_AND_LOC)); + if (source_print) + { + if (print_location_source) + out->text ("\n"); /* Newline after the location source. */ + print_source_lines (sal.symtab, sal.line, sal.line + 1, 0); } /* For MI we need to deal with the "children" list population of @@ -973,7 +1031,9 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, if (! out->is_mi_like_p ()) { annotate_frame_end (); - out->text ("\n"); + /* print_source_lines has already printed a newline. */ + if (!source_print) + out->text ("\n"); } if (print_locals) @@ -996,8 +1056,7 @@ py_print_frame (PyObject *filter, frame_filter_flags flags, ui_out_emit_list inner_list_emiter (out, "children"); - if (! out->is_mi_like_p ()) - indent++; + indent++; while ((item = PyIter_Next (elided.get ()))) { @@ -1060,21 +1119,6 @@ bootstrap_python_frame_filters (struct frame_info *frame, return iterable.release (); } -/* A helper function that will either print an exception or, if it is - a KeyboardException, throw a quit. This can only be called when - the Python exception is set. */ - -static void -throw_quit_or_print_exception () -{ - if (PyErr_ExceptionMatches (PyExc_KeyboardInterrupt)) - { - PyErr_Clear (); - throw_quit ("Quit"); - } - gdbpy_print_stack (); -} - /* This is the only publicly exported function in this file. FRAME is the source frame to start frame-filter invocation. FLAGS is an integer holding the flags for printing. The following elements of @@ -1102,16 +1146,15 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang, if (!gdb_python_initialized) return EXT_LANG_BT_NO_FILTERS; - TRY + try { gdbarch = get_frame_arch (frame); } - CATCH (except, RETURN_MASK_ERROR) + catch (const gdb_exception_error &except) { /* Let gdb try to print the stack trace. */ return EXT_LANG_BT_NO_FILTERS; } - END_CATCH gdbpy_enter enter_py (gdbarch, current_language); @@ -1145,7 +1188,7 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang, initialization error. This return code will trigger a default backtrace. */ - throw_quit_or_print_exception (); + gdbpy_print_stack_or_quit (); return EXT_LANG_BT_NO_FILTERS; } @@ -1168,7 +1211,7 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang, { if (PyErr_Occurred ()) { - throw_quit_or_print_exception (); + gdbpy_print_stack_or_quit (); return EXT_LANG_BT_ERROR; } break; @@ -1187,22 +1230,21 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang, } } - TRY + try { success = py_print_frame (item.get (), flags, args_type, out, 0, levels_printed.get ()); } - CATCH (except, RETURN_MASK_ERROR) + catch (const gdb_exception_error &except) { gdbpy_convert_exception (except); success = EXT_LANG_BT_ERROR; } - END_CATCH /* Do not exit on error printing a single frame. Print the error and continue with other frames. */ if (success == EXT_LANG_BT_ERROR) - throw_quit_or_print_exception (); + gdbpy_print_stack_or_quit (); } return success;