From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 30965 invoked by alias); 18 Jul 2012 13:27:20 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 30912 invoked by uid 9514); 18 Jul 2012 13:27:16 -0000 Date: Wed, 18 Jul 2012 13:27:00 -0000 Message-ID: <20120718132716.30895.qmail@sourceware.org> From: pmuldoon@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer-pmuldoon-python-backtrace: Use python to process frame args and frame locals. Add constants for apply_frame_filter return status. Use simpler elide testcase X-Git-Refname: refs/heads/archer-pmuldoon-python-backtrace X-Git-Reftype: branch X-Git-Oldrev: a81b9451ed963f10a9e7470dfabfbf5946a53462 X-Git-Newrev: 625ff3032449b7f1cd3a9672080c666710cb5c31 X-SW-Source: 2012-q3/txt/msg00010.txt.bz2 List-Id: The branch, archer-pmuldoon-python-backtrace has been updated via 625ff3032449b7f1cd3a9672080c666710cb5c31 (commit) from a81b9451ed963f10a9e7470dfabfbf5946a53462 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit 625ff3032449b7f1cd3a9672080c666710cb5c31 Author: Phil Muldoon Date: Wed Jul 18 14:26:23 2012 +0100 Use python to process frame args and frame locals. Add constants for apply_frame_filter return status. Use simpler elide testcase ----------------------------------------------------------------------- Summary of changes: gdb/python/lib/gdb/BaseFrameWrapper.py | 77 ++++-- gdb/python/lib/gdb/command/frame_filters.py | 8 +- gdb/python/py-frame.c | 159 ---------- gdb/python/py-framefilter.c | 417 +++++++++++++++------------ gdb/python/python.h | 5 + gdb/stack.c | 4 +- gdb/testsuite/gdb.python/py-framefilter.py | 93 ++---- 7 files changed, 335 insertions(+), 428 deletions(-) First 500 lines of diff: diff --git a/gdb/python/lib/gdb/BaseFrameWrapper.py b/gdb/python/lib/gdb/BaseFrameWrapper.py index c24463e..bb9974e 100644 --- a/gdb/python/lib/gdb/BaseFrameWrapper.py +++ b/gdb/python/lib/gdb/BaseFrameWrapper.py @@ -27,9 +27,9 @@ class BaseFrameWrapper (FrameWrapper): super(BaseFrameWrapper, self).__init__(base) self.base = base - def elide (self): - if hasattr(self.base, "elide"): - return self.base.elide() + def elided (self): + if hasattr(self.base, "elided"): + return self.base.elided() return None @@ -63,27 +63,15 @@ class BaseFrameWrapper (FrameWrapper): if hasattr(self.base, "frame_args"): return self.base.frame_args() - args = self.base.arguments() - args_list = [] - if args != None: - for arg in args: - value = arg.value(self.base) - args_list.append((arg, value)) - - return args_list + args = FrameVars (self.base) + return args.fetch_frame_args() def frame_locals (self): if hasattr(self.base, "frame_locals"): return self.base.frame_locals() - frame_locals = self.base.locals() - frame_locals_list = [] - if frame_locals != None: - for frame_local in frame_locals: - value = frame_local.value(self.base) - frame_locals_list.append((frame_local, value)) - - return frame_locals_list + args = FrameVars (self.base) + return args.fetch_frame_locals() def line (self): if hasattr(self.base, "line"): @@ -100,3 +88,54 @@ class BaseFrameWrapper (FrameWrapper): return self.base.inferior_frame() return self.base + +class FrameVars (): + + def __init__(self,frame): + self.frame = frame + + def fetch_frame_locals (self): + frame_vars = [] + block = self.frame.block() + + for sym in block: + if sym.is_argument: + continue; + frame_vars.append((sym, self.get_value (sym, block))) + + if len(frame_vars) == 0: + return None + + return iter (frame_vars) + + def fetch_frame_args (self): + frame_args = [] + block = self.frame.block() + + for sym in block: + if not sym.is_argument: + continue; + + frame_args.append((sym, self.get_value (sym,block))) + + if len(frame_args) == 0: + return None + + return iter (frame_args) + + def get_value (self, sym, block): + if len (sym.linkage_name): + nsym, is_field_of_this = gdb.lookup_symbol (sym.linkage_name, block) + + if nsym.addr_class != gdb.SYMBOL_LOC_REGISTER: + sym = nsym + + try: + val = sym.value (self.frame) + + except RuntimeError, text: + val = text + if val == None: + val = "???" + + return val diff --git a/gdb/python/lib/gdb/command/frame_filters.py b/gdb/python/lib/gdb/command/frame_filters.py index 59ec9b2..8b71ab7 100644 --- a/gdb/python/lib/gdb/command/frame_filters.py +++ b/gdb/python/lib/gdb/command/frame_filters.py @@ -159,12 +159,18 @@ def invoke (frame): Arguments: frame_iterator: An iterator of frames. """ + sorted_list = _sort_list() + + # Check to see if there are any frame-filters. If not, just + # return None and let default backtrace printing occur. + if len(sorted_list) == 0: + return None + frame_iterator = FrameIterator (frame) # Apply base filter to all gdb.Frames. This unifies the in # interface - frame_iterator = itertools.imap (BaseFrameWrapper, frame_iterator) for ff in sorted_list: diff --git a/gdb/python/py-frame.c b/gdb/python/py-frame.c index c500f50..12a54e8 100644 --- a/gdb/python/py-frame.c +++ b/gdb/python/py-frame.c @@ -519,159 +519,6 @@ gdbpy_newest_frame (PyObject *self, PyObject *args) return frame_obj; } - -/* Implementation of gdb.arguments () -> List - Returns a list of gdb.Symbols that constitute this frame's - arguments. */ - -static PyObject * -frapy_frame_args (PyObject *self, PyObject *args) -{ - struct frame_info *fi; - struct symbol *func = NULL; - volatile struct gdb_exception except; - PyObject *list = NULL; - int err = 0, size = 0; - - TRY_CATCH (except, RETURN_MASK_ALL) - { - FRAPY_REQUIRE_VALID (self, fi); - - func = find_pc_function (get_frame_address_in_block (fi)); - - if (func) - { - list = PyList_New (0); - - if (! list) - err = 1; - else - { - struct dict_iterator iter; - struct block *b = SYMBOL_BLOCK_VALUE (func); - struct symbol *arg_sym; - - for (arg_sym = dict_iterator_first (BLOCK_DICT (b), &iter); - arg_sym != NULL; - arg_sym = dict_iterator_next (&iter)) - { - PyObject *arg_obj = NULL; - - if (!SYMBOL_IS_ARGUMENT (arg_sym)) - continue; - - if (*SYMBOL_LINKAGE_NAME (arg_sym)) - { - struct symbol *nsym; - - nsym = lookup_symbol (SYMBOL_LINKAGE_NAME (arg_sym), - b, VAR_DOMAIN, NULL); - if (SYMBOL_CLASS (nsym) == LOC_REGISTER - && !SYMBOL_IS_ARGUMENT (nsym)) - { - continue; - /* skip. */ - } - else - arg_sym = nsym; - } - - size++; - /* Cannot "return" in a exception handler. */ - arg_obj = symbol_to_symbol_object (arg_sym); - if (! arg_obj) - { - err = 1; - break; - } - if (PyList_Append (list, arg_obj) == -1) - { - err = 1; - break; - } - } - } - } - } - GDB_PY_HANDLE_EXCEPTION (except); - - if (err) - { - Py_XDECREF (list); - return NULL; - } - - /* No arguments, return None. */ - if (size ==0) - { - Py_XDECREF (list); - Py_RETURN_NONE; - } - - return list; -} - -static void -do_build_locals_list (const char *print_name, - struct symbol *sym, - void *cb_data) -{ - PyObject *llist = (PyObject *) cb_data; - PyObject *psym = symbol_to_symbol_object (sym); - - if (psym) - PyList_Append (llist, psym); -} - -/* Implementation of gdb.locals () -> List - Returns a list of gdb.Symbols that constitute this frame's - local variables. */ - -static PyObject * -frapy_frame_locals (PyObject *self, PyObject *args) -{ - struct frame_info *fi; - volatile struct gdb_exception except; - PyObject *list = NULL; - int err = 0; - struct block *b; - - TRY_CATCH (except, RETURN_MASK_ALL) - { - FRAPY_REQUIRE_VALID (self, fi); - - list = PyList_New (0); - - if (! list) - err = 1; - else - { - b = get_frame_block (fi, 0); - iterate_over_block_local_vars (b, - do_build_locals_list, - list); - if (PyErr_Occurred ()) - err = 1; - } - } - GDB_PY_HANDLE_EXCEPTION (except); - - if (err) - { - Py_XDECREF (list); - return NULL; - } - - /* No arguments, return None. */ - if (PyList_Size (list) <= 0) - { - Py_XDECREF (list); - Py_RETURN_NONE; - } - - return list; -} - /* Implementation of gdb.selected_frame () -> gdb.Frame. Returns the selected frame object. */ @@ -797,12 +644,6 @@ Return the frame's code block." }, { "function", frapy_function, METH_NOARGS, "function () -> gdb.Symbol.\n\ Returns the symbol for the function corresponding to this frame." }, - { "arguments", frapy_frame_args, METH_NOARGS, - "arguments () -> List.\n\ -Returns a List containing symbols of all frame arguments, or None." }, - { "locals", frapy_frame_locals, METH_NOARGS, - "locals () -> List.\n\ -Returns a List containing symbols of all frame locals, or None." }, { "older", frapy_older, METH_NOARGS, "older () -> gdb.Frame.\n\ Return the frame that called this frame." }, diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c index 304e243..d10fb63 100644 --- a/gdb/python/py-framefilter.c +++ b/gdb/python/py-framefilter.c @@ -34,6 +34,67 @@ #include "python-internal.h" static int +extract_value (PyObject *tuple, char **name, + struct value **value, + const struct language_defn **language) +{ + PyObject *sym, *pvalue; + + /* Each element in the locals arguments list should be a + tuple containing two elements. The local name, + which can be a string or a gdb.Symbol, and the + value. */ + + /* Name. */ + sym = PyTuple_GetItem (tuple, 0); + if (! sym) + return 0; + + /* Value. */ + pvalue = PyTuple_GetItem (tuple, 1); + if (! pvalue) + return 0; + + /* For arg name, the user can return a symbol or a + string. */ + if (PyString_Check (sym)) + { + *name = python_string_to_host_string (sym); + if (! name) + return 0; + *language = current_language; + } + else + { + struct symbol *symbol = symbol_object_to_symbol (sym); + if (! symbol) + { + PyErr_SetString (PyExc_RuntimeError, + _("Unexpected value in tuple. " \ + "Expecting being a gdb.Symbol or a " \ + "Python string.")); + return 0; + } + + *name = xstrdup (SYMBOL_PRINT_NAME (symbol)); + + if (language_mode == language_mode_auto) + *language = language_def (SYMBOL_LANGUAGE (symbol)); + else + *language = current_language; + } + + *value = convert_value_from_python (pvalue); + if (! *value) + { + xfree (*name); + return 0; + } + + return 1; +} + +static int py_print_locals (PyObject *filter, struct value_print_options opts) { @@ -42,110 +103,93 @@ py_print_locals (PyObject *filter, if (PyObject_HasAttrString (filter, "frame_locals")) { - PyObject *result = PyObject_CallMethod (filter, "frame_locals", NULL); - volatile struct gdb_exception except; - const struct language_defn *language; + PyObject *result = PyObject_CallMethod (filter, "frame_locals", + NULL); if (result) { - Py_ssize_t size, list_index; - make_cleanup_py_decref (result); - if (! PyList_Check (result)) - { - PyErr_SetString (PyExc_RuntimeError, - _("frame_locals must return a Python list.")); - goto locals_error; - } - - size = PyList_Size (result); - - for (list_index = 0; list_index < size; list_index++) + if (result != Py_None) { - PyObject *sym_tuple, *sym, *value; - char *sym_name; - struct value *val; - struct symbol *symbol; - - sym_tuple = PyList_GetItem (result, list_index); - if (! sym_tuple) - goto locals_error; - - if (! PyTuple_Check (sym_tuple) - && PyTuple_Size (sym_tuple) != 2) + if (! PyIter_Check (result)) { PyErr_SetString (PyExc_RuntimeError, - _("frame_locals list must contain a Python tuple.")); + _("'frame_locals' function must " \ + "return an iterator.")); goto locals_error; } - - /* Each element in the locals arguments list should be a - tuple containing two elements. The local name, - which can be a string or a gdb.Symbol, and the - value. */ - - /* Name. */ - sym = PyTuple_GetItem (sym_tuple, 0); - if (! sym) - goto locals_error; - - /* Value. */ - value = PyTuple_GetItem (sym_tuple, 1); - if (! value) - goto locals_error; - - /* For arg name, the user can return a symbol or a - string. */ - if (PyString_Check (sym)) - { - sym_name = python_string_to_host_string (sym); - language = current_language; - if (! sym_name) - goto locals_error; - } else { - symbol = symbol_object_to_symbol (sym); - sym_name = xstrdup (SYMBOL_PRINT_NAME (symbol)); + PyObject *iterator = PyObject_GetIter (result); + PyObject *item; - if (language_mode == language_mode_auto) - language = language_def (SYMBOL_LANGUAGE (symbol)); - else - language = current_language; - } - - fprintf_filtered (gdb_stdout, "%s%s = ", - n_spaces (2 * indent), sym_name); - xfree (sym_name); - - val = value_object_to_value (value); - if (! val) - { - PyErr_SetString (PyExc_RuntimeError, - _("Invalid value in frame.")); - goto locals_error; - } + if (! iterator) + goto locals_error; - TRY_CATCH (except, RETURN_MASK_ERROR) - { - opts.deref_ref = 1; - common_val_print (val, gdb_stdout, indent, &opts, language); - } - if (except.reason < 0) - { - PyErr_SetString (PyExc_RuntimeError, - except.message); - goto locals_error; + while ((item = PyIter_Next (iterator))) + { + const struct language_defn *language; + char *sym_name; + struct value *val; + int value_success = 0; + volatile struct gdb_exception except; + + if (! item) + goto locals_error; + + if (! PyTuple_Check (item) + && PyTuple_Size (item) != 2) + { hooks/post-receive -- Repository for Project Archer.