public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] archer-pmuldoon-python-backtrace: Add initial support for -stack-list-variables. Rewrite locals and argument aquisition and prining to account for the combined nature of -stack-list-variables
@ 2012-08-14 15:38 pmuldoon
0 siblings, 0 replies; only message in thread
From: pmuldoon @ 2012-08-14 15:38 UTC (permalink / raw)
To: archer-commits
The branch, archer-pmuldoon-python-backtrace has been updated
via 12f3ffcbc3530fb011af47e03f6dabfb96f42147 (commit)
from ee73819ce0a91fd1e20670770445f5a50d7d7ec6 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit 12f3ffcbc3530fb011af47e03f6dabfb96f42147
Author: Phil Muldoon <pmuldoon@redhat.com>
Date: Tue Aug 14 16:37:49 2012 +0100
Add initial support for -stack-list-variables. Rewrite locals and
argument aquisition and prining to account for the combined nature of
-stack-list-variables
-----------------------------------------------------------------------
Summary of changes:
gdb/mi/mi-cmd-stack.c | 44 +++-
gdb/python/py-framefilter.c | 563 ++++++++++++++++++++++++------------------
gdb/python/py-utils.c | 27 ++
gdb/python/python-internal.h | 1 +
4 files changed, 395 insertions(+), 240 deletions(-)
First 500 lines of diff:
diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c
index 92ab4c2..f3e1309 100644
--- a/gdb/mi/mi-cmd-stack.c
+++ b/gdb/mi/mi-cmd-stack.c
@@ -353,13 +353,49 @@ void
mi_cmd_stack_list_variables (char *command, char **argv, int argc)
{
struct frame_info *frame;
+ int raw_arg = 0;
+ int result = 0;
- if (argc != 1)
- error (_("Usage: PRINT_VALUES"));
+ if (argc == 2)
+ {
+ int j;
+ /* Find 'raw-frames' at argv[1] if passed as an argument */
+ for (j = 0; j < strlen (argv[1]); j++)
+ argv[1][j] = tolower (argv[1][j]);
- frame = get_selected_frame (NULL);
+ if (subset_compare (argv[1], "raw-frames"))
+ raw_arg = 1;
+ }
- list_args_or_locals (all, parse_print_values (argv[0]), frame);
+ if (argc < 1 || argc > 2 || (argc == 2 && ! raw_arg)
+ || (argc == 1 && raw_arg))
+ error (_("-stack-list-arguments: Usage: PRINT_VALUES [RAW-FRAMES]"));
+
+ frame = get_selected_frame (NULL);
+
+ if (! raw_arg && frame_filters)
+ {
+ int count = 1;
+ int arg = atoi (argv[0]);
+
+ result = apply_frame_filter (frame,/* frame */
+ 1, /* print_level */
+ LOC_AND_ADDRESS, /* print_what */
+ 0, /* print_frame_info */
+ 1, /* print_args */
+ arg, /* mi_print_args_type */
+ 0, /* cli_print_args_type */
+ current_uiout, /* out */
+ 1, /* print_locals */
+ count /* count */);
+ }
+
+ if (! frame_filters || raw_arg || result == PY_BT_ERROR
+ || result == PY_BT_NO_FILTERS)
+ {
+
+ list_args_or_locals (all, parse_print_values (argv[0]), frame);
+ }
}
/* Print single local or argument. ARG must be already read in. For
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
index 14217f3..fd6e26e 100644
--- a/gdb/python/py-framefilter.c
+++ b/gdb/python/py-framefilter.c
@@ -34,11 +34,21 @@
#ifdef HAVE_PYTHON
#include "python-internal.h"
-static int
-extract_sym_and_value (PyObject *obj, char **name,
- struct value **value,
- const struct language_defn **language)
+/* Helper function to extract a name, value and language definition
+ from a Python object that conforms SymbolValue interface. OBJ is
+ the Python object to extract the values from. **NAME is a
+ pass-through argument where the name of the symbol will be written.
+ **VALUE is a pass-through argument where the value corresponding
+ the to the Symbol will be written, and LANGUAGE is also a
+ pass-through argument denoting the language attributed to the
+ Symbol. Returns 0 on error with the appropriate Python exception
+ set, and 1 on success. */
+
+static int extract_sym_and_value (PyObject *obj,
+ char **name, struct value **value,
+ const struct language_defn **language)
{
+
if (PyObject_HasAttrString (obj, "symbol"))
{
PyObject *result = PyObject_CallMethod (obj, "symbol", NULL);
@@ -62,6 +72,7 @@ extract_sym_and_value (PyObject *obj, char **name,
struct symbol *symbol = symbol_object_to_symbol (result);
Py_DECREF (result);
+
if (! symbol)
{
PyErr_SetString (PyExc_RuntimeError,
@@ -112,12 +123,16 @@ extract_sym_and_value (PyObject *obj, char **name,
"implemented."));
return 0;
}
+
return 1;
}
+/* Helper function which outputs a type name to a stream. OUT is the
+ ui-out structure the type name will be output too, and VAL is the
+ value that the type will be extracted from. Returns 0 on error,
+ with any GDB exceptions converted to a Python exception. */
static int
-py_print_type (struct ui_out *out,
- struct value *val)
+py_print_type (struct ui_out *out, struct value *val)
{
volatile struct gdb_exception except;
@@ -140,132 +155,318 @@ py_print_type (struct ui_out *out,
except.message);
return 0;
}
-
return 1;
}
+/* Helper function which outputs a value name to a stream. OUT is the
+ ui-out structure the value will be output too, and VAL is the value
+ that will be printed. LANGUAGE is the language_defn that the value
+ will be printed with. Returns 0 on error, with any GDB exceptions
+ converted to a Python exception. */
+
static int
-py_print_locals (PyObject *filter,
- struct ui_out *out,
- struct value_print_options opts,
- int mi_print_type,
- int indent)
+py_print_value (struct ui_out *out, struct value *val,
+ const struct language_defn *language)
{
- /* In traditional bt full backtraces this is num_tabs (4) * 2 = 8. It
- never appears to deviate from this. */
- struct cleanup *old_chain = make_cleanup_ui_out_list_begin_end (out,
- "locals");
+ volatile struct gdb_exception except;
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ struct ui_file *stb;
+ struct cleanup *cleanup;
+ struct value_print_options opts;
- if (PyObject_HasAttrString (filter, "frame_locals"))
+ stb = mem_fileopen ();
+ cleanup = make_cleanup_ui_file_delete (stb);
+ get_user_print_options (&opts);
+ opts.deref_ref = 1;
+ common_val_print (val, stb, 2, &opts, language);
+ ui_out_field_stream (out, "value", stb);
+ do_cleanups (cleanup);
+ }
+ if (except.reason > 0)
{
- PyObject *result = PyObject_CallMethod (filter, "frame_locals",
- NULL);
+ PyErr_SetString (PyExc_RuntimeError,
+ except.message);
+ return 0;
+ }
+ return 1;
+}
+
+/* Helper function to call a Python method and extract an iterator
+ from the result, error checking for Python exception and returns
+ that are not iterators. FILTER is the Python object to call, and
+ FUNC is the name of the method. Returns a PyObject, or NULL on
+ error with the appropriate exception set. */
+
+static PyObject *
+get_py_iter_from_func (PyObject *filter, char *func)
+{
+ if (PyObject_HasAttrString (filter, func))
+ {
+ PyObject *result = PyObject_CallMethod (filter, func, NULL);
if (result)
{
- make_cleanup_py_decref (result);
-
if (result != Py_None)
{
if (! PyIter_Check (result))
{
PyErr_SetString (PyExc_RuntimeError,
- _("'frame_locals' function must " \
- "return an iterator."));
- goto locals_error;
+ strcat (func, _(" function must " \
+ "return an iterator.")));
+ Py_DECREF (result);
+ return NULL;
}
else
{
PyObject *iterator = PyObject_GetIter (result);
- PyObject *item;
+
+ Py_DECREF (result);
if (! iterator)
- goto locals_error;
+ return NULL;
+ else
+ return iterator;
+ }
+ }
+ }
+ else
+ return NULL;
+ }
- make_cleanup_py_decref (iterator);
- 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;
- struct cleanup *inner_cleanup =
- make_cleanup (null_cleanup, NULL);
-
- value_success = extract_sym_and_value (item, &sym_name,
- &val,
- &language);
+ Py_RETURN_NONE;
+}
- Py_DECREF (item);
+static int
+enumerate_args (PyObject *iter,
+ struct ui_out *out,
+ struct value_print_options opts,
+ int mi_print_type,
+ const char *print_args_type,
+ int print_mi_args_flag)
+{
+ PyObject *item;
- if (! value_success)
- goto locals_error;
-
- if (ui_out_is_mi_like_p (out))
- {
- if (mi_print_type != PRINT_NO_VALUES)
- {
- inner_cleanup =
- make_cleanup_ui_out_tuple_begin_end (out,
- NULL);
- }
- }
- else
- ui_out_spaces (out, (8 + (indent * 2)));
-
- ui_out_field_string (out, "name", sym_name);
- xfree (sym_name);
-
- if (! ui_out_is_mi_like_p (out))
- ui_out_text (out, " = ");
-
- if (ui_out_is_mi_like_p (out)
- && mi_print_type == PRINT_SIMPLE_VALUES)
- {
- if (! py_print_type (out, val))
- goto locals_error;
- }
-
- if (! ui_out_is_mi_like_p (out)
- || (ui_out_is_mi_like_p (out)
- && mi_print_type != PRINT_NO_VALUES))
- {
- struct ui_file *stb;
- stb = mem_fileopen ();
- make_cleanup_ui_file_delete (stb);
-
- TRY_CATCH (except, RETURN_MASK_ALL)
- {
- get_user_print_options (&opts);
- opts.deref_ref = 1;
- common_val_print (val, stb, 2, &opts, language);
- }
- if (except.reason > 0)
- {
- PyErr_SetString (PyExc_RuntimeError,
- except.message);
- goto locals_error;
- }
-
- ui_out_field_stream (out, "value", stb);
- }
-
- ui_out_text (out, "\n");
- do_cleanups (inner_cleanup);
+ annotate_frame_args ();
- }
+ item = PyIter_Next (iter);
+ if (! item && PyErr_Occurred ())
+ goto error;
- if (! item && PyErr_Occurred())
- goto locals_error;
- }
+ while (item)
+ {
+ const struct language_defn *language;
+ char *sym_name;
+ struct value *val;
+ int value_success = 0;
+ volatile struct gdb_exception except;
+ struct cleanup *inner_cleanup =
+ make_cleanup (null_cleanup, NULL);
+
+ value_success = extract_sym_and_value (item,
+ &sym_name,
+ &val,
+ &language);
+ Py_DECREF (item);
+ item = NULL;
+
+ if (! value_success)
+ goto error;
+
+ if (ui_out_is_mi_like_p (out))
+ {
+ if(mi_print_type != PRINT_NO_VALUES)
+ {
+ inner_cleanup =
+ make_cleanup_ui_out_tuple_begin_end (out,
+ NULL);
+ }
+ }
+
+ annotate_arg_begin ();
+ ui_out_field_string (out, "name", sym_name);
+
+ if (! ui_out_is_mi_like_p (out))
+ ui_out_text (out, "=");
+
+ if (print_mi_args_flag)
+ ui_out_field_int (out, "arg", 1);
+
+ annotate_arg_value (value_type (val));
+ opts.deref_ref = 1;
+
+ if (ui_out_is_mi_like_p (out)
+ && mi_print_type == PRINT_SIMPLE_VALUES)
+ {
+ py_print_type (out, val);
+ }
+
+ if (! ui_out_is_mi_like_p (out))
+ {
+ opts.summary = !strcmp (print_args_type, "scalars");
+ }
+
+ if (! ui_out_is_mi_like_p (out)
+ || (ui_out_is_mi_like_p (out)
+ && mi_print_type != PRINT_NO_VALUES))
+ {
+ py_print_value (out, val, language);
+ }
+
+ do_cleanups (inner_cleanup);
+
+ /* Collect the next item from the iterator. If
+ this is the last item, we do not print the
+ ",". */
+ item = PyIter_Next (iter);
+ if (item)
+ ui_out_text (out, ", ");
+ else
+ if (PyErr_Occurred ())
+ goto error;
+
+ annotate_arg_end ();
+ }
+
+ return 1;
+
+ error:
+ return 0;
+}
+
+static int
+enumerate_locals (PyObject *iter,
+ struct ui_out *out,
+ struct value_print_options opts,
+ int mi_print_type,
+ int indent)
+{
+ PyObject *item;
+
+ while ((item = PyIter_Next (iter)))
+ {
+ const struct language_defn *language;
+ char *sym_name;
+ struct value *val;
+ int value_success = 0;
+ volatile struct gdb_exception except;
+ struct cleanup *inner_cleanup =
+ make_cleanup (null_cleanup, NULL);
+
+ value_success = extract_sym_and_value (item, &sym_name,
+ &val,
+ &language);
+
+ Py_DECREF (item);
+
+ if (! value_success)
+ goto error;
+
+ if (ui_out_is_mi_like_p (out))
+ {
+ if (mi_print_type != PRINT_NO_VALUES)
+ {
+ inner_cleanup =
+ make_cleanup_ui_out_tuple_begin_end (out,
+ NULL);
}
}
else
- goto locals_error;
+ ui_out_spaces (out, (8 + (indent * 2)));
+
+ ui_out_field_string (out, "name", sym_name);
+ xfree (sym_name);
+
+ if (! ui_out_is_mi_like_p (out))
+ ui_out_text (out, " = ");
+
+ if (ui_out_is_mi_like_p (out)
+ && mi_print_type == PRINT_SIMPLE_VALUES)
+ {
+ if (! py_print_type (out, val))
+ goto error;
+ }
+
+ if (! ui_out_is_mi_like_p (out)
+ || (ui_out_is_mi_like_p (out)
+ && mi_print_type != PRINT_NO_VALUES))
+ {
+ py_print_value (out, val, language);
+ }
+
+ ui_out_text (out, "\n");
+ do_cleanups (inner_cleanup);
}
+ if (! item && PyErr_Occurred())
+ goto error;
+
+ done:
+ return 1;
+
+ error:
+ return 0;
+}
+
+static int
+py_mi_print_variables (PyObject *filter, struct ui_out *out,
+ struct value_print_options opts,
+ int mi_print_type, const char *print_args_type)
+{
+ struct cleanup *old_chain;
+ PyObject *args_iter;
+ PyObject *locals_iter;
+
+ args_iter = get_py_iter_from_func (filter, "frame_args");
+ old_chain = make_cleanup_py_xdecref (args_iter);
+ if (! args_iter)
+ goto error;
+
+ locals_iter = get_py_iter_from_func (filter, "frame_locals");
+ if (! locals_iter)
+ goto error;
+
+ make_cleanup_py_decref (locals_iter);
+ make_cleanup_ui_out_list_begin_end (out, "variables");
+
+ if (args_iter != Py_None)
+ if (! enumerate_args (args_iter, out, opts, mi_print_type,
+ print_args_type, 1))
+ goto error;
+
+ if (locals_iter != Py_None)
+ if (! enumerate_locals (locals_iter, out, opts,
+ mi_print_type, 0))
+ goto error;
+
+ do_cleanups (old_chain);
+ return 1;
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2012-08-14 15:38 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-14 15:38 [SCM] archer-pmuldoon-python-backtrace: Add initial support for -stack-list-variables. Rewrite locals and argument aquisition and prining to account for the combined nature of -stack-list-variables pmuldoon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).