public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] archer-pmuldoon-python-backtrace: Add support for entry arguments and initial support for -stack-list-arguments.
@ 2012-08-23 14:53 pmuldoon
0 siblings, 0 replies; only message in thread
From: pmuldoon @ 2012-08-23 14:53 UTC (permalink / raw)
To: archer-commits
The branch, archer-pmuldoon-python-backtrace has been updated
via 8a1e1772259968d49dd6a96c4e9b86fdbce3e130 (commit)
from ce126c971ee4f1908c026de832cedd633c4028b5 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit 8a1e1772259968d49dd6a96c4e9b86fdbce3e130
Author: Phil Muldoon <pmuldoon@redhat.com>
Date: Thu Aug 23 15:52:41 2012 +0100
Add support for entry arguments and initial support for -stack-list-arguments.
-----------------------------------------------------------------------
Summary of changes:
gdb/python/lib/gdb/BaseFrameWrapper.py | 4 +-
gdb/python/py-framefilter.c | 460 ++++++++++++++++++------
gdb/testsuite/gdb.python/py-framefilter-mi.c | 27 ++-
gdb/testsuite/gdb.python/py-framefilter-mi.exp | 40 ++-
4 files changed, 403 insertions(+), 128 deletions(-)
First 500 lines of diff:
diff --git a/gdb/python/lib/gdb/BaseFrameWrapper.py b/gdb/python/lib/gdb/BaseFrameWrapper.py
index e4ca58d..aa49ad1 100644
--- a/gdb/python/lib/gdb/BaseFrameWrapper.py
+++ b/gdb/python/lib/gdb/BaseFrameWrapper.py
@@ -133,7 +133,7 @@ class FrameVars ():
if sym.is_argument:
continue;
if self.fetch_b (sym):
- lvars.append(BaseSymValueWrapper(sym, self.get_value(sym,block)))
+ lvars.append(BaseSymValueWrapper(sym, None))
if len(lvars) == 0:
return None
@@ -148,7 +148,7 @@ class FrameVars ():
if not sym.is_argument:
continue;
if self.fetch_b (sym):
- args.append(BaseSymValueWrapper(sym,self.get_value (sym,block)))
+ args.append(BaseSymValueWrapper(sym,None))
if len(args) == 0:
return None
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
index fd6e26e..9183c54 100644
--- a/gdb/python/py-framefilter.c
+++ b/gdb/python/py-framefilter.c
@@ -23,32 +23,33 @@
#include "language.h"
#include "exceptions.h"
#include "arch-utils.h"
-#include "language.h"
#include "python.h"
#include "ui-out.h"
#include "valprint.h"
#include "annotate.h"
#include "hashtab.h"
#include "mi/mi-cmds.h"
+#include "demangle.h"
#ifdef HAVE_PYTHON
#include "python-internal.h"
-/* 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
+
+/* Helper function to extract a symbol, name and language definition
+ from a Python object that conforms to the 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)
-{
+ **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 0 on error with
+ the appropriate Python exception set, and 1 on success. */
+static int
+extract_sym (PyObject *obj, char **name, struct symbol **sym,
+ const struct language_defn **language)
+{
if (PyObject_HasAttrString (obj, "symbol"))
{
PyObject *result = PyObject_CallMethod (obj, "symbol", NULL);
@@ -66,14 +67,15 @@ static int extract_sym_and_value (PyObject *obj,
if (! *name)
return 0;
*language = current_language;
+ *sym = NULL;
}
else
{
- struct symbol *symbol = symbol_object_to_symbol (result);
+ *sym = symbol_object_to_symbol (result);
Py_DECREF (result);
- if (! symbol)
+ if (! *sym)
{
PyErr_SetString (PyExc_RuntimeError,
_("Unexpected value. Expecting a " \
@@ -81,10 +83,10 @@ static int extract_sym_and_value (PyObject *obj,
return 0;
}
- *name = xstrdup (SYMBOL_PRINT_NAME (symbol));
+ *name = xstrdup (SYMBOL_PRINT_NAME (*sym));
if (language_mode == language_mode_auto)
- *language = language_def (SYMBOL_LANGUAGE (symbol));
+ *language = language_def (SYMBOL_LANGUAGE (*sym));
else
*language = current_language;
}
@@ -92,37 +94,52 @@ static int extract_sym_and_value (PyObject *obj,
else
{
PyErr_SetString (PyExc_RuntimeError,
- _("Mandatory function 'symbol' not " \
+ _("Mandatory function 'symbol' not " \
"implemented."));
return 0;
}
+ return 1;
+}
+
+/* Helper function to extract a value from an object that conforms to
+ the SymbolValue interface. OBJ is the Python object to extract the
+ value from. **VALUE is a pass-through argument where the value
+ will be written. If the object does not have the value attribute,
+ or provides the Python None for a value, **VALUE will be set to
+ NULL and this function will return as successful. Returns 0 on
+ error with the appropriate Python exception set, and 1 on
+ success. */
+
+static int
+extract_value (PyObject *obj, struct value **value)
+{
if (PyObject_HasAttrString (obj, "value"))
{
- PyObject *result = PyObject_CallMethod (obj, "value", NULL);
+ PyObject *vresult = PyObject_CallMethod (obj, "value", NULL);
- if (! result)
+ if (! vresult)
+ return 0;
+
+ if (vresult == Py_None)
{
- xfree (*name);
- return 0;
+ Py_DECREF (vresult);
+ *value = NULL;
+ return 1;
}
+ else
+ {
+ *value = convert_value_from_python (vresult);
+ Py_DECREF (vresult);
- *value = convert_value_from_python (result);
+ if (*value == NULL)
+ return 0;
- Py_DECREF (result);
- if (! *value)
- {
- xfree (*name);
- return 0;
+ return 1;
}
}
else
- {
- PyErr_SetString (PyExc_RuntimeError,
- _("Mandatory function 'value' not " \
- "implemented."));
- return 0;
- }
+ *value = NULL;
return 1;
}
@@ -145,7 +162,7 @@ py_print_type (struct ui_out *out, struct value *val)
stb = mem_fileopen ();
cleanup = make_cleanup_ui_file_delete (stb);
type = check_typedef (value_type (val));
- type_print (type, "", stb, -1);
+ type_print (value_type (val), "", stb, -1);
ui_out_field_stream (out, "type", stb);
do_cleanups (cleanup);
}
@@ -166,30 +183,54 @@ py_print_type (struct ui_out *out, struct value *val)
static int
py_print_value (struct ui_out *out, struct value *val,
+ struct value_print_options opts,
+ int mi_print_type,
const struct language_defn *language)
{
- volatile struct gdb_exception except;
+ int should_print = 0;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ /* MI disallows different value types against different options the
+ client passes, so test type against option. For CLI print all
+ values. */
+ if (ui_out_is_mi_like_p (out))
{
- struct ui_file *stb;
- struct cleanup *cleanup;
- struct value_print_options opts;
+ struct type *type;
- 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);
+ type = value_type (val);
+ check_typedef (type);
+ if (mi_print_type == PRINT_ALL_VALUES
+ || (mi_print_type == PRINT_SIMPLE_VALUES
+ && TYPE_CODE (type) != TYPE_CODE_ARRAY
+ && TYPE_CODE (type) != TYPE_CODE_STRUCT
+ && TYPE_CODE (type) != TYPE_CODE_UNION))
+ should_print = 1;
}
- if (except.reason > 0)
+ else
+ should_print = 1;
+
+ if (should_print)
{
- PyErr_SetString (PyExc_RuntimeError,
- except.message);
- return 0;
+ volatile struct gdb_exception except;
+
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ struct ui_file *stb;
+ struct cleanup *cleanup;
+
+ stb = mem_fileopen ();
+ cleanup = make_cleanup_ui_file_delete (stb);
+ common_val_print (val, stb, 0, &opts, language);
+ ui_out_field_stream (out, "value", stb);
+ do_cleanups (cleanup);
+ }
+ if (except.reason > 0)
+ {
+ PyErr_SetString (PyExc_RuntimeError,
+ except.message);
+ return 0;
+ }
}
+
return 1;
}
@@ -239,12 +280,113 @@ get_py_iter_from_func (PyObject *filter, char *func)
}
static int
+py_print_single_arg (struct ui_out *out,
+ char *sym_name,
+ struct frame_arg *fa,
+ struct value *fv,
+ struct value_print_options opts,
+ int mi_print_type,
+ const char *print_args_type,
+ int print_mi_args_flag,
+ const struct language_defn *language)
+{
+ struct value *val;
+ struct cleanup *inner_cleanup =
+ make_cleanup (null_cleanup, NULL);
+
+ if (fa)
+ {
+ language = language_def (SYMBOL_LANGUAGE (fa->sym));
+ val = fa->val;
+ }
+ else
+ val = fv;
+
+ if (print_mi_args_flag || mi_print_type != PRINT_NO_VALUES)
+ {
+ inner_cleanup =
+ make_cleanup_ui_out_tuple_begin_end (out,
+ NULL);
+ }
+
+ annotate_arg_begin ();
+
+ if (fa)
+ {
+ struct ui_file *stb;
+
+ stb = mem_fileopen ();
+
+ fprintf_symbol_filtered (stb, SYMBOL_PRINT_NAME (fa->sym),
+ SYMBOL_LANGUAGE (fa->sym),
+ DMGL_PARAMS | DMGL_ANSI);
+ if (fa->entry_kind == print_entry_values_compact)
+ {
+ fputs_filtered ("=", stb);
+
+ fprintf_symbol_filtered (stb, SYMBOL_PRINT_NAME (fa->sym),
+ SYMBOL_LANGUAGE (fa->sym),
+ DMGL_PARAMS | DMGL_ANSI);
+ }
+ if (fa->entry_kind == print_entry_values_only
+ || fa->entry_kind == print_entry_values_compact)
+ {
+ fputs_filtered ("@entry", stb);
+ }
+ ui_out_field_stream (out, "name", stb);
+ ui_file_delete (stb);
+ }
+ else
+ ui_out_field_string (out, "name", sym_name);
+
+ annotate_arg_name_end ();
+
+ if (! ui_out_is_mi_like_p (out))
+ ui_out_text (out, "=");
+
+ if (print_mi_args_flag)
+ ui_out_field_int (out, "arg", 1);
+
+ opts.deref_ref = 1;
+ 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))
+ {
+ opts.summary = !strcmp (print_args_type, "scalars");
+ }
+
+ annotate_arg_value (value_type (val));
+ if (! ui_out_is_mi_like_p (out)
+ || (ui_out_is_mi_like_p (out)
+ && mi_print_type != PRINT_NO_VALUES))
+ {
+
+ if (! py_print_value (out, val, opts, mi_print_type, language))
+ goto error;
+ }
+
+ do_cleanups (inner_cleanup);
+
+ return 1;
+
+ error:
+ do_cleanups (inner_cleanup);
+ return 0;
+}
+
+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)
+ int print_mi_args_flag,
+ struct frame_info *frame)
{
PyObject *item;
@@ -258,63 +400,103 @@ enumerate_args (PyObject *iter,
{
const struct language_defn *language;
char *sym_name;
+ struct symbol *sym;
struct value *val;
- int value_success = 0;
+ int success = 0;
volatile struct gdb_exception except;
- struct cleanup *inner_cleanup =
- make_cleanup (null_cleanup, NULL);
+ struct frame_arg arg, entryarg;
+
+ success = extract_sym (item, &sym_name, &sym, &language);
+ if (! success)
+ {
+ Py_DECREF (item);
+ goto error;
+ }
+
+ success = extract_value (item, &val);
+ if (! success)
+ {
+ xfree (sym_name);
+ Py_DECREF (item);
+ goto error;
+ }
- 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 the object did not provide a value, read it. */
+ if (! val)
{
- if(mi_print_type != PRINT_NO_VALUES)
+
+ /* If there is no value, and also no symbol, set error and
+ exit. */
+ if (! sym)
{
- inner_cleanup =
- make_cleanup_ui_out_tuple_begin_end (out,
- NULL);
+ PyErr_SetString (PyExc_RuntimeError,
+ _("No symbol or value provided."));
+ xfree (sym_name);
+ goto error;
}
- }
- annotate_arg_begin ();
- ui_out_field_string (out, "name", sym_name);
+ read_frame_arg (sym, frame, &arg, &entryarg);
+ }
- if (! ui_out_is_mi_like_p (out))
- ui_out_text (out, "=");
- if (print_mi_args_flag)
- ui_out_field_int (out, "arg", 1);
+ /* If the object has provided a value, we print that. */
+ if (val)
+ py_print_single_arg (out,
+ sym_name,
+ NULL,
+ val,
+ opts,
+ mi_print_type,
+ print_args_type,
+ print_mi_args_flag,
+ language);
+ else
+ {
+ /* The object has not provided a value, so this is a frame
+ argument read by GDB. In this case we have to account
+ for entry-values. */
+
+ if (arg.entry_kind != print_entry_values_only)
+ py_print_single_arg (out,
+ NULL,
+ &arg,
+ NULL,
+ opts,
+ mi_print_type,
+ print_args_type,
+ print_mi_args_flag,
+ NULL);
+
+
+ if (entryarg.entry_kind != print_entry_values_no)
+ {
+ if (arg.entry_kind != print_entry_values_only)
+ {
+ ui_out_text (out, ", ");
+ ui_out_wrap_hint (out, " ");
+ }
- annotate_arg_value (value_type (val));
- opts.deref_ref = 1;
+ py_print_single_arg (out,
+ NULL,
+ &entryarg,
+ NULL,
+ opts,
+ mi_print_type,
+ print_args_type,
+ print_mi_args_flag,
+ NULL);
- 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");
+ xfree (arg.error);
+ xfree (entryarg.error);
}
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2012-08-23 14:53 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-23 14:53 [SCM] archer-pmuldoon-python-backtrace: Add support for entry arguments and initial support for -stack-list-arguments 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).