public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] archer-pmuldoon-python-backtrace: Refactor frame argument printing. Roughly implement print local variables.
@ 2012-03-27 16:39 pmuldoon
0 siblings, 0 replies; only message in thread
From: pmuldoon @ 2012-03-27 16:39 UTC (permalink / raw)
To: archer-commits
The branch, archer-pmuldoon-python-backtrace has been updated
via 6a48d614cf35d16e6f4ac3b7cacba5682d9c445e (commit)
from 91c892b685cdcea5a1a23f358b322517b22ebc51 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit 6a48d614cf35d16e6f4ac3b7cacba5682d9c445e
Author: Phil Muldoon <pmuldoon@redhat.com>
Date: Tue Mar 27 17:38:55 2012 +0100
Refactor frame argument printing. Roughly implement print local
variables.
-----------------------------------------------------------------------
Summary of changes:
gdb/python/py-framefilter.c | 436 ++++++++++++++++++---------
gdb/python/python.h | 5 +-
gdb/stack.c | 17 +-
gdb/testsuite/gdb.python/py-framefilter.c | 17 +
gdb/testsuite/gdb.python/py-framefilter.exp | 1 +
gdb/testsuite/gdb.python/py-framefilter.py | 39 +++
6 files changed, 369 insertions(+), 146 deletions(-)
First 500 lines of diff:
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
index 9a96bae..f5ce701 100644
--- a/gdb/python/py-framefilter.c
+++ b/gdb/python/py-framefilter.c
@@ -246,7 +246,279 @@ find_frame_filter (PyObject *frame, int print_level,
}
static int
-print_frame (PyObject *filter,
+py_print_locals (PyObject *filter,
+ struct value_print_options opts)
+{
+ int indent = 4;
+ struct ui_stream *stb;
+ struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
+
+ if (PyObject_HasAttrString (filter, "frame_locals"))
+ {
+ PyObject *result = PyObject_CallMethod (filter, "frame_locals", NULL);
+ volatile struct gdb_exception except;
+ const struct language_defn *language;
+
+ 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);
+
+ if (size > 0)
+ {
+ for (list_index = 0; list_index < size; list_index++)
+ {
+ 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)
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("frame_locals list must contain a Python tuple."));
+ 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));
+
+ 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;
+ }
+
+ 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;
+ }
+ fprintf_filtered (gdb_stdout, "\n");
+
+ gdb_flush (gdb_stdout);
+ }
+ }
+ }
+ else
+ goto locals_error;
+ }
+
+ do_cleanups (old_chain);
+ return 1;
+
+ locals_error:
+ do_cleanups (old_chain);
+ return 0;
+}
+
+static int
+py_print_args (PyObject *filter,
+ struct ui_out *out,
+ struct value_print_options opts,
+ const char *print_args_type)
+{
+ struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
+ PyObject *result = NULL;
+ struct ui_stream *stb = NULL;
+
+ /* Frame arguments. */
+ annotate_frame_args ();
+ ui_out_text (out, " (");
+
+ if (PyObject_HasAttrString (filter, "frame_args"))
+ {
+ PyObject *result = PyObject_CallMethod (filter, "frame_args", NULL);
+ volatile struct gdb_exception except;
+ const struct language_defn *language;
+
+ result = PyObject_CallMethod (filter, "frame_args", NULL);
+
+ if (result)
+ {
+ Py_ssize_t size, list_index;
+
+ make_cleanup_py_decref (result);
+ stb = ui_out_stream_new (out);
+ make_cleanup_ui_out_stream_delete (stb);
+
+ if (! PyList_Check (result))
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("frame_args must return a Python list."));
+ goto args_error;
+ }
+
+ size = PyList_Size (result);
+
+ if (size > 0)
+ {
+ for (list_index = 0; list_index < size; list_index++)
+ {
+ PyObject *sym_tuple, *sym, *value;
+ const char *sym_name;
+ struct value *val;
+ struct symbol *symbol;
+
+ sym_tuple = PyList_GetItem (result, list_index);
+ if (! sym_tuple)
+ goto args_error;
+
+ if (! PyTuple_Check (sym_tuple)
+ && PyTuple_Size (sym_tuple) != 2)
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("frame_arg list must contain a Python tuple."));
+ goto args_error;
+ }
+
+ /* Each element in the frame arguments list should be a
+ tuple containing two elements. The argument name,
+ which can be a string or a gdb.Symbol, and the
+ value. */
+
+ /* Name. */
+ sym = PyTuple_GetItem (sym_tuple, 0);
+ if (! sym)
+ goto args_error;
+
+ /* Value. */
+ value = PyTuple_GetItem (sym_tuple, 1);
+ if (! value)
+ goto args_error;
+
+ /* For arg name, the user can return a symbol or a
+ string. */
+ if (PyString_Check (sym))
+ {
+ sym_name = PyString_AsString (sym);
+ language = current_language;
+ if (! sym_name)
+ goto args_error;
+ }
+ else
+ {
+ symbol = symbol_object_to_symbol (sym);
+ sym_name = SYMBOL_PRINT_NAME (symbol);
+ if (language_mode == language_mode_auto)
+ language = language_def (SYMBOL_LANGUAGE (symbol));
+ else
+ language = current_language;
+ }
+
+ annotate_arg_begin ();
+ ui_out_field_string (out, "name", sym_name);
+ ui_out_text (out, "=");
+
+ val = value_object_to_value (value);
+ if (! val)
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ _("Invalid value in frame."));
+ goto args_error;
+ }
+
+ annotate_arg_value (value_type (val));
+
+ opts.deref_ref = 1;
+
+ /* True in "summary" mode, false otherwise. */
+ opts.summary = !strcmp (print_args_type, "scalars");
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ common_val_print (val, stb->stream, 2, &opts, language);
+ }
+ if (except.reason > 0)
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ except.message);
+ goto args_error;
+ }
+
+ ui_out_field_stream (out, "value", stb);
+
+ if (size != 1 && list_index < size-1)
+ ui_out_text (out, ", ");
+ annotate_arg_end ();
+ }
+ }
+ }
+ else
+ goto args_error;
+ }
+ ui_out_text (out, ")");
+
+ do_cleanups (old_chain);
+ return 1;
+
+ args_error:
+ do_cleanups (old_chain);
+ return 0;
+}
+
+static int
+py_print_frame (PyObject *filter,
int print_level,
enum print_what print_what,
int print_args,
@@ -263,7 +535,6 @@ print_frame (PyObject *filter,
char *filename = NULL;
int line = 0;
volatile struct gdb_exception except;
- const struct language_defn *language;
/* First check to see if this frame is to be omitted. */
if (PyObject_HasAttrString (filter, "omit"))
@@ -374,136 +645,12 @@ print_frame (PyObject *filter,
ui_out_field_string (out, "func", func);
/* Frame arguments. */
- annotate_frame_args ();
- ui_out_text (out, " (");
if (print_args)
{
- if (PyObject_HasAttrString (filter, "frame_args"))
- {
- PyObject *result = PyObject_CallMethod (filter, "frame_args", NULL);
- struct ui_stream *stb;
- struct cleanup *old_chain;
- const char *sym_name;
-
- stb = ui_out_stream_new (out);
- old_chain = make_cleanup_ui_out_stream_delete (stb);
-
- if (result)
- {
- Py_ssize_t size, list_index;
-
- if (! PyList_Check (result))
- {
- Py_DECREF (result);
- PyErr_SetString (PyExc_RuntimeError,
- _("frame_args must return a Python list."));
- do_cleanups (old_chain);
- goto error;
- }
-
- size = PyList_Size (result);
-
- if (size > 0)
- {
- for (list_index = 0; list_index < size; list_index++)
- {
- PyObject *sym_tuple, *sym, *value;
- char *symname;
- struct value *val;
- struct symbol *symbol;
-
- sym_tuple = PyList_GetItem (result, list_index);
- if (! sym_tuple)
- {
- Py_DECREF (result);
- do_cleanups (old_chain);
- goto error;
- }
-
- if (! PyTuple_Check (sym_tuple)
- && PyTuple_Size (sym_tuple) != 2)
- {
- Py_DECREF (result);
-
- PyErr_SetString (PyExc_RuntimeError,
- _("frame_arg list must contain a Python tuple."));
- do_cleanups (old_chain);
- goto error;
- }
-
- /* Each element in the frame arguments list should be a
- tuple containing two elements. The argument name,
- which can be a string or a gdb.Symbol, and the
- value. */
-
- /* Name. */
- sym = PyTuple_GetItem (sym_tuple, 0);
- if (! sym)
- {
- Py_DECREF (result);
- do_cleanups (old_chain);
- goto error;
- }
-
- /* Value. */
- value = PyTuple_GetItem (sym_tuple, 1);
- if (! value)
- {
- Py_DECREF (result);
- do_cleanups (old_chain);
- goto error;
- }
-
- /* For arg name, the user can return a symbol or a
- string. */
- if (PyString_Check (sym))
- {
- sym_name = PyString_AsString (sym);
- language = current_language;
- if (! sym_name)
- {
- Py_DECREF (result);
- do_cleanups (old_chain);
- goto error;
- }
- }
- else
- {
- symbol = symbol_object_to_symbol (sym);
- sym_name = SYMBOL_PRINT_NAME (symbol);
- if (language_mode == language_mode_auto)
- language = language_def (SYMBOL_LANGUAGE (symbol));
- else
- language = current_language;
- }
-
- annotate_arg_begin ();
- ui_out_field_string (out, "name", sym_name);
- ui_out_text (out, "=");
-
- val = value_object_to_value (value);
-
- annotate_arg_value (value_type (val));
-
- opts.deref_ref = 1;
-
- /* True in "summary" mode, false otherwise. */
- opts.summary = !strcmp (print_args_type, "scalars");
- common_val_print (val, stb->stream, 2, &opts, language);
- ui_out_field_stream (out, "value", stb);
- if (size != 1 && list_index < size-1)
- ui_out_text (out, ", ");
- annotate_arg_end ();
- }
- Py_DECREF (result);
- }
- }
- else
- goto error;
- }
+ if (! py_print_args (filter, out, opts, print_args_type))
+ goto error;
}
- ui_out_text (out, ")");
if (PyObject_HasAttrString (filter, "filename"))
{
PyObject *result = PyObject_CallMethod (filter, "filename", NULL);
@@ -613,7 +760,8 @@ int
apply_frame_filter (struct frame_info *frame, int print_level,
enum print_what print_what, int print_args,
const char *print_args_type,
- struct ui_out *out)
+ struct ui_out *out, int print_frame,
+ int print_locals)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
struct cleanup *cleanups;
@@ -638,16 +786,21 @@ apply_frame_filter (struct frame_info *frame, int print_level,
goto done;
get_user_print_options (&opts);
- success = print_frame (filter, print_level, print_what,
- print_args, print_args_type, out, opts,
- frame);
-
+ if (print_frame)
+ {
+ success = py_print_frame (filter, print_level, print_what,
+ print_args, print_args_type, out, opts,
+ frame);
+ if (success == 0 && PyErr_Occurred ())
+ gdbpy_print_stack ();
+ }
- /* 'print_frame' can return a frame to "resume" from, in the case
- that frames have been elided. If the return value is NULL, also
- check to see if this was because a Python error occurred. */
- if (success == 0 && PyErr_Occurred())
- gdbpy_print_stack ();
+ if (print_locals)
+ {
+ success = py_print_locals (filter, opts);
+ if (success == 0 && PyErr_Occurred ())
+ gdbpy_print_stack ();
+ }
done:
do_cleanups (cleanups);
@@ -655,11 +808,12 @@ apply_frame_filter (struct frame_info *frame, int print_level,
}
#else /* HAVE_PYTHON */
-
-struct frame_info *
+int
apply_frame_filter (struct frame_info *frame, int print_level,
enum print_what print_what, int print_args,
- struct ui_out *out)
+ const char *print_args_type,
+ struct ui_out *out, int print_frame,
+ int print_locals)
{
return NULL;
}
diff --git a/gdb/python/python.h b/gdb/python/python.h
index 80f7168..55ec72b 100644
--- a/gdb/python/python.h
+++ b/gdb/python/python.h
@@ -39,12 +39,15 @@ int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
const struct value_print_options *options,
const struct language_defn *language);
+
int apply_frame_filter (struct frame_info *frame,
int print_level,
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2012-03-27 16:39 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-27 16:39 [SCM] archer-pmuldoon-python-backtrace: Refactor frame argument printing. Roughly implement print local 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).