public inbox for archer-commits@sourceware.org help / color / mirror / Atom feed
From: pmuldoon@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer-pmuldoon-python-backtrace: Fix several exception handling cases, remove unecessary arguments and add a substantial amount of comments. Date: Thu, 30 Aug 2012 16:57:00 -0000 [thread overview] Message-ID: <20120830165741.12943.qmail@sourceware.org> (raw) 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.
reply other threads:[~2012-08-30 16:57 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20120830165741.12943.qmail@sourceware.org \ --to=pmuldoon@sourceware.org \ --cc=archer-commits@sourceware.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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).