public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] archer-pmuldoon-python-backtrace: Fix several exception handling cases, remove unecessary arguments and add a substantial amount of comments.
@ 2012-08-30 16:57 pmuldoon
0 siblings, 0 replies; only message in thread
From: pmuldoon @ 2012-08-30 16:57 UTC (permalink / raw)
To: archer-commits
The branch, archer-pmuldoon-python-backtrace has been updated
via 0b8f3279654cca66be3ddbcc3b8603d83f1317b5 (commit)
from d7f9500d9e6602fb6067a5881e74c5420dbaf9c8 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit 0b8f3279654cca66be3ddbcc3b8603d83f1317b5
Author: Phil Muldoon <pmuldoon@redhat.com>
Date: Thu Aug 30 17:56:40 2012 +0100
Fix several exception handling cases, remove unecessary arguments and
add a substantial amount of comments.
-----------------------------------------------------------------------
Summary of changes:
gdb/mi/mi-cmd-stack.c | 4 -
gdb/python/py-framefilter.c | 304 +++++++++++++++++++++++++------------------
gdb/python/python.h | 8 +-
gdb/stack.c | 1 -
4 files changed, 184 insertions(+), 133 deletions(-)
First 500 lines of diff:
diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c
index f3e1309..47c2b4c 100644
--- a/gdb/mi/mi-cmd-stack.c
+++ b/gdb/mi/mi-cmd-stack.c
@@ -115,7 +115,6 @@ mi_cmd_stack_list_frames (char *command, char **argv, int argc)
count = (frame_high - frame_low) + 1;
result = apply_frame_filter (fi,/* frame */
1, /* print_level */
- LOC_AND_ADDRESS, /* print_what */
1, /* print_frame_info */
0, /* print_args */
0, /* mi_print_args_type */
@@ -226,7 +225,6 @@ mi_cmd_stack_list_locals (char *command, char **argv, int argc)
result = apply_frame_filter (frame,/* frame */
1, /* print_level */
- LOC_AND_ADDRESS, /* print_what */
0, /* print_frame_info */
0, /* print_args */
arg, /* mi_print_args_type */
@@ -312,7 +310,6 @@ mi_cmd_stack_list_args (char *command, char **argv, int argc)
result = apply_frame_filter (fi,/* frame */
1, /* print_level */
- LOC_AND_ADDRESS, /* print_what */
0, /* print_frame_info */
1, /* print_args */
print_values, /* mi_print_args_type */
@@ -380,7 +377,6 @@ mi_cmd_stack_list_variables (char *command, char **argv, int argc)
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 */
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
index 9183c54..96106fc 100644
--- a/gdb/python/py-framefilter.c
+++ b/gdb/python/py-framefilter.c
@@ -36,19 +36,21 @@
/* Helper function to extract a symbol, name and language definition
- from a Python object that conforms to the SymbolValue interface.
+ from a Python object that conforms to the "Symbol Value" 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.
- **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. */
+ **NAME is allocated in this function, but the caller is responsible
+ for clean up. **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)
+ const struct language_defn **language)
{
if (PyObject_HasAttrString (obj, "symbol"))
{
@@ -71,6 +73,8 @@ extract_sym (PyObject *obj, char **name, struct symbol **sym,
}
else
{
+ /* This type checks 'result' during the conversion so we
+ just call it unconditionally and check the return. */
*sym = symbol_object_to_symbol (result);
Py_DECREF (result);
@@ -83,6 +87,8 @@ extract_sym (PyObject *obj, char **name, struct symbol **sym,
return 0;
}
+ /* Duplicate the symbol name, so the caller has consistency
+ in garbage collection. */
*name = xstrdup (SYMBOL_PRINT_NAME (*sym));
if (language_mode == language_mode_auto)
@@ -103,8 +109,8 @@ extract_sym (PyObject *obj, char **name, struct symbol **sym,
}
/* 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
+ the "Symbol Value" 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
@@ -121,6 +127,9 @@ extract_value (PyObject *obj, struct value **value)
if (! vresult)
return 0;
+ /* The Python code has returned 'None' for a value, so we set
+ value to NULL. This flags that GDB should read the
+ value. */
if (vresult == Py_None)
{
Py_DECREF (vresult);
@@ -144,10 +153,12 @@ extract_value (PyObject *obj, struct value **value)
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. */
+/* Helper function which outputs a type name to a "type" field in 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)
{
@@ -175,11 +186,14 @@ py_print_type (struct ui_out *out, struct value *val)
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. */
+/* Helper function which outputs a value name to value field in a
+ stream. OUT is the ui-out structure the value will be output too,
+ VAL is the value that will be printed, OPTS contains the value
+ printing options, MI_PRINT_TYPE is the value delimiter for MI
+ output and LANGUAGE is the language_defn that the value will be
+ printed with. If the output is detected to be non-MI,
+ MI_PRINT_TYPE is ignored. Returns 0 on error, with any GDB
+ exceptions converted to a Python exception. */
static int
py_print_value (struct ui_out *out, struct value *val,
@@ -238,7 +252,8 @@ py_print_value (struct ui_out *out, struct value *val,
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. */
+ error with the appropriate exception set. This function can return
+ an iterator, or None. */
static PyObject *
get_py_iter_from_func (PyObject *filter, char *func)
@@ -253,9 +268,9 @@ get_py_iter_from_func (PyObject *filter, char *func)
{
if (! PyIter_Check (result))
{
- PyErr_SetString (PyExc_RuntimeError,
- strcat (func, _(" function must " \
- "return an iterator.")));
+ PyErr_Format (PyExc_RuntimeError,
+ _(" %s function must " \
+ "return an iterator."), func);
Py_DECREF (result);
return NULL;
}
@@ -279,6 +294,18 @@ get_py_iter_from_func (PyObject *filter, char *func)
Py_RETURN_NONE;
}
+/* Helper function to output a single frame argument and value to an
+ output stream, accounting for entry values if the passed argument
+ has them. Will output in CLI or MI like format depending on the
+ type of output. OUT is the output stream , SYM_NAME is the name
+ of the symbol if this a synthetic argument (one which does not
+ have a backing symbol. If SYM_NAME is populated then it must have
+ an accompanying value in the parameter FV. FA is a frame argument
+ structure. If this is populated, both SYM_NAME and FV are
+ ignored. OPTS contains the value printing options, MI_PRINT_TYPE
+ is an enumerator to the value types that will be printed if the
+ output is MI. PRINT_MI_ARGS indciates whether to output the ARGS
+ field in MI output. */
static int
py_print_single_arg (struct ui_out *out,
char *sym_name,
@@ -286,7 +313,6 @@ py_print_single_arg (struct ui_out *out,
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)
{
@@ -302,6 +328,8 @@ py_print_single_arg (struct ui_out *out,
else
val = fv;
+ /* MI has varying rules for tuples, but generally if there is only
+ one element in each item in the list, do not start a tuple. */
if (print_mi_args_flag || mi_print_type != PRINT_NO_VALUES)
{
inner_cleanup =
@@ -311,6 +339,8 @@ py_print_single_arg (struct ui_out *out,
annotate_arg_begin ();
+ /* If frame argument is populated, check for entry-values and the
+ entry value options. */
if (fa)
{
struct ui_file *stb;
@@ -337,6 +367,7 @@ py_print_single_arg (struct ui_out *out,
ui_file_delete (stb);
}
else
+ /* Otherwise, just output the name. */
ui_out_field_string (out, "name", sym_name);
annotate_arg_name_end ();
@@ -348,6 +379,8 @@ py_print_single_arg (struct ui_out *out,
ui_out_field_int (out, "arg", 1);
opts.deref_ref = 1;
+
+ /* For MI print the type. */
if (ui_out_is_mi_like_p (out)
&& mi_print_type == PRINT_SIMPLE_VALUES)
{
@@ -355,12 +388,10 @@ py_print_single_arg (struct ui_out *out,
goto error;
}
- if (! ui_out_is_mi_like_p (out))
- {
- opts.summary = !strcmp (print_args_type, "scalars");
- }
-
annotate_arg_value (value_type (val));
+
+ /* If CLI, always print values. For MI do not print values if the
+ enumerator is PRINT_NO_VALUES. */
if (! ui_out_is_mi_like_p (out)
|| (ui_out_is_mi_like_p (out)
&& mi_print_type != PRINT_NO_VALUES))
@@ -379,12 +410,21 @@ py_print_single_arg (struct ui_out *out,
return 0;
}
+/* Helper function to loop over frame arguments provided by the
+ frame_arguments Python API. Elements in the iterator must conform
+ to the "Symbol Value" interface. ITER is the Python iterator
+ object, OUT is the output stream, OPTS contains the value printing
+ options, MI_PRINT_TYPE is an enumerator to the value types that
+ will be printed if the output is MI, PRINT_MI_ARGS indciates
+ whether to output the ARGS field in MI output, and FRAME is the
+ backing frame. If (all) the frame argument values are provided via
+ the value API call, FRAME is not needed. */
+
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,
struct frame_info *frame)
{
@@ -392,6 +432,10 @@ enumerate_args (PyObject *iter,
annotate_frame_args ();
+ /* Collect the first argument outside of the loop, so output of
+ commas in the argument output is correct. At the end of the
+ loop block collect another item from the iterator, and, if it is
+ not null emit a comma. */
item = PyIter_Next (iter);
if (! item && PyErr_Occurred ())
goto error;
@@ -404,7 +448,6 @@ enumerate_args (PyObject *iter,
struct value *val;
int success = 0;
volatile struct gdb_exception except;
- struct frame_arg arg, entryarg;
success = extract_sym (item, &sym_name, &sym, &language);
if (! success)
@@ -424,9 +467,11 @@ enumerate_args (PyObject *iter,
Py_DECREF (item);
item = NULL;
- /* If the object did not provide a value, read it. */
+ /* If the object did not provide a value, read it using
+ read_frame_args and account for entry values, if any. */
if (! val)
{
+ struct frame_arg arg, entryarg;
/* If there is no value, and also no symbol, set error and
exit. */
@@ -438,38 +483,26 @@ enumerate_args (PyObject *iter,
goto error;
}
- read_frame_arg (sym, frame, &arg, &entryarg);
- }
-
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ read_frame_arg (sym, frame, &arg, &entryarg);
+ }
+ if (except.reason > 0)
+ {
+ xfree (sym_name);
+ PyErr_SetString (PyExc_RuntimeError,
+ except.message);
+ goto error;
+ }
- /* 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. */
+ argument to be 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,
+ py_print_single_arg (out, NULL, &arg, NULL, opts,
mi_print_type,
- print_args_type,
- print_mi_args_flag,
- NULL);
-
+ print_mi_args_flag, NULL);
if (entryarg.entry_kind != print_entry_values_no)
{
@@ -479,28 +512,28 @@ enumerate_args (PyObject *iter,
ui_out_wrap_hint (out, " ");
}
- py_print_single_arg (out,
- NULL,
- &entryarg,
- NULL,
- opts,
+ py_print_single_arg (out, NULL, &entryarg, NULL, opts,
mi_print_type,
- print_args_type,
- print_mi_args_flag,
- NULL);
-
+ print_mi_args_flag, NULL);
}
xfree (arg.error);
xfree (entryarg.error);
}
+ else
+ {
+ /* If the object has provided a value, we just print that. */
+ if (val)
+ py_print_single_arg (out, sym_name, NULL, val, opts,
+ mi_print_type,
+ print_mi_args_flag, language);
+ }
xfree (sym_name);
-
/* Collect the next item from the iterator. If
- this is the last item, we do not print the
- ",". */
+ this is the last item, do not print the
+ comma. */
item = PyIter_Next (iter);
if (item)
ui_out_text (out, ", ");
@@ -517,6 +550,17 @@ enumerate_args (PyObject *iter,
return 0;
}
+
+/* Helper function to loop over variables provided by the frame_locals
+ Python API. Elements in the iterator must conform to the "Symbol
+ Value" interface. ITER is the Python iterator object, OUT is the
+ output stream, OPTS contains the value printing options,
+ MI_PRINT_TYPE is an enumerator to the value types that will be
+ printed if the output is MI, PRINT_MI_ARGS_FLAG indciates whether
+ to output the ARGS field in MI output, and FRAME is the backing
+ frame. If (all) of the variables values are provided via the value
+ API call, FRAME is not needed. */
+
static int
enumerate_locals (PyObject *iter,
struct ui_out *out,
@@ -560,11 +604,22 @@ enumerate_locals (PyObject *iter,
/* If the object did not provide a value, read it. */
if (! val)
{
- val = read_var_value (sym, frame);
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ val = read_var_value (sym, frame);
+ }
+ if (except.reason > 0)
+ {
+ xfree (sym_name);
+ PyErr_SetString (PyExc_RuntimeError,
+ except.message);
+ goto error;
+ }
}
- /* With PRINT_NO_VALUES, MI does not emit a tuple, unless in
- -stack-list-variables. */
+ /* With PRINT_NO_VALUES, MI does not emit a tuple normally as
+ each output contains only one field. The exception is
+ -stack-list-variables, which always provides a tuple. */
if (ui_out_is_mi_like_p (out))
{
if (print_mi_args_flag || mi_print_type != PRINT_NO_VALUES)
@@ -575,6 +630,7 @@ enumerate_locals (PyObject *iter,
}
}
else
+ /* If the output is not MI we indent locals. */
ui_out_spaces (out, (8 + (indent * 2)));
ui_out_field_string (out, "name", sym_name);
@@ -611,10 +667,12 @@ enumerate_locals (PyObject *iter,
return 0;
}
+/* Help function for -stack-list-variables. */
+
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,
+ int mi_print_type,
struct frame_info *frame)
{
struct cleanup *old_chain;
@@ -635,7 +693,7 @@ py_mi_print_variables (PyObject *filter, struct ui_out *out,
if (args_iter != Py_None)
if (! enumerate_args (args_iter, out, opts, mi_print_type,
- print_args_type, 1, frame))
+ 1, frame))
goto error;
if (locals_iter != Py_None)
@@ -651,6 +709,9 @@ py_mi_print_variables (PyObject *filter, struct ui_out *out,
return 0;
}
+/* Helper function for printing locals. This function largely just
+ creates the wrapping tuple, and calls enumerate_locals. */
+
static int
py_print_locals (PyObject *filter,
struct ui_out *out,
@@ -680,12 +741,15 @@ py_print_locals (PyObject *filter,
return 0;
}
+/* Helper function for printing frame arguments. This function
+ largely just creates the wrapping tuple, and calls
+ enumerate_args. */
+
static int
py_print_args (PyObject *filter,
struct ui_out *out,
struct value_print_options opts,
int mi_print_type,
- const char *print_args_type,
struct frame_info *frame)
{
PyObject *args_iter = get_py_iter_from_func (filter, "frame_args");
@@ -702,7 +766,7 @@ py_print_args (PyObject *filter,
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2012-08-30 16:57 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-30 16:57 [SCM] archer-pmuldoon-python-backtrace: Fix several exception handling cases, remove unecessary arguments and add a substantial amount of comments 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).