public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] archer-pmuldoon-python-backtrace: Implement omit and (bogus, non duck typed) elide function.
@ 2012-03-19 15:06 pmuldoon
0 siblings, 0 replies; only message in thread
From: pmuldoon @ 2012-03-19 15:06 UTC (permalink / raw)
To: archer-commits
The branch, archer-pmuldoon-python-backtrace has been updated
via d34a750b8b79c1260f21e8c25f61b7197448d78f (commit)
from 0e5e6d2d84fbf0a975c4f83017c845805b7d1ae2 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit d34a750b8b79c1260f21e8c25f61b7197448d78f
Author: Phil Muldoon <pmuldoon@redhat.com>
Date: Mon Mar 19 15:05:11 2012 +0000
Implement omit and (bogus, non duck typed) elide function.
-----------------------------------------------------------------------
Summary of changes:
gdb/frame.c | 23 ++++
gdb/frame.h | 6 +
gdb/python/py-framefilter.c | 145 +++++++++++++++++++++++----
gdb/python/python.h | 6 +-
gdb/stack.c | 18 +++-
gdb/testsuite/gdb.python/py-framefilter.c | 3 +-
gdb/testsuite/gdb.python/py-framefilter.exp | 4 +-
gdb/testsuite/gdb.python/py-framefilter.py | 34 +++++--
8 files changed, 197 insertions(+), 42 deletions(-)
First 500 lines of diff:
diff --git a/gdb/frame.c b/gdb/frame.c
index e012f2d..3e0cb40 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -127,6 +127,11 @@ struct frame_info
/* The reason why we could not set PREV, or UNWIND_NO_REASON if we
could. Only valid when PREV_P is set. */
enum unwind_stop_reason stop_reason;
+
+ /* In Python frame-filtering, we can "elide" frames. Store state
+ (during printing and processing) if this frame has been elided by
+ another. */
+ int elide;
};
/* A frame stash used to speed up frame lookups. */
@@ -2217,6 +2222,24 @@ frame_relative_level (struct frame_info *fi)
return fi->level;
}
+int
+frame_print_elide (struct frame_info *fi)
+{
+ if (fi == NULL)
+ return -1;
+ else
+ return fi->elide;
+}
+
+void
+set_frame_print_elide (struct frame_info *fi)
+{
+ if (fi == NULL)
+ return;
+ else
+ fi->elide = 1;
+}
+
enum frame_type
get_frame_type (struct frame_info *frame)
{
diff --git a/gdb/frame.h b/gdb/frame.h
index 7b42b56..c027c81 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -428,6 +428,12 @@ extern CORE_ADDR get_frame_args_address (struct frame_info *);
for an invalid frame). */
extern int frame_relative_level (struct frame_info *fi);
+/* Whether this frame has been marked as elided for printing
+ purposes. */
+extern int frame_print_elide (struct frame_info *fi);
+
+extern void set_frame_print_elide (struct frame_info *fi);
+
/* Return the frame's type. */
extern enum frame_type get_frame_type (struct frame_info *);
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
index d156d7f..ea4edfc 100644
--- a/gdb/python/py-framefilter.c
+++ b/gdb/python/py-framefilter.c
@@ -18,7 +18,6 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
-#include "exceptions.h"
#include "objfiles.h"
#include "symtab.h"
#include "language.h"
@@ -247,8 +246,10 @@ find_frame_filter (PyObject *frame, int print_level,
}
static int
-print_frame (PyObject *filter, int print_level,
- enum print_what print_what, int print_args,
+print_frame (PyObject *filter,
+ int print_level,
+ enum print_what print_what,
+ int print_args,
struct ui_out *out,
struct value_print_options opts,
struct frame_info *frame)
@@ -260,18 +261,53 @@ print_frame (PyObject *filter, int print_level,
char *func = NULL;
char *filename = NULL;
int line = 0;
+ volatile struct gdb_exception except;
+
+ /* First check to see if this frame is to be omitted. */
+ if (PyObject_HasAttrString (filter, "omit"))
+ {
+ PyObject *result = PyObject_CallMethod (filter, "omit", NULL);
+
+ if (result)
+ {
+ int omit = 0;
+
+ if (! PyBool_Check (result))
+ {
+ Py_DECREF (result);
+ PyErr_SetString (PyExc_RuntimeError,
+ _("'omit' must return type boolean."));
+ goto error;
+ }
+
+ omit = PyObject_IsTrue (result);
+
+ Py_DECREF (result);
+
+ if (omit == -1)
+ goto error;
+ else if (omit)
+ return 1;
+ }
+ else
+ goto error;
+ }
if (print_level)
{
if (PyObject_HasAttrString (filter, "level"))
{
- PyObject *result = PyObject_CallMethod (filter, "level", NULL);
+ PyObject *result = PyObject_CallMethod (filter, "level", "i",
+ frame_relative_level (frame),
+ NULL);
if (result)
{
level = PyLong_AsLong (result);
Py_DECREF (result);
}
+ else
+ goto error;
}
else
level = frame_relative_level (frame);
@@ -286,6 +322,8 @@ print_frame (PyObject *filter, int print_level,
address = PyLong_AsLong (result);
Py_DECREF (result);
}
+ else
+ goto error;
}
else
address = 0;
@@ -311,15 +349,21 @@ print_frame (PyObject *filter, int print_level,
if (result)
{
char *dup = PyString_AsString (result);
- if (dup)
- func = xstrdup (dup);
- else
- return 0;
+ if (! dup)
+ {
+ Py_DECREF (result);
+ goto error;
+ }
+
+ func = xstrdup (dup);
+
Py_DECREF (result);
}
+ else
+ goto error;
}
else
- func = xstrdup("<unknown>");
+ func = xstrdup ("<unknown>");
annotate_frame_function_name ();
ui_out_field_string (out, "func", func);
@@ -331,12 +375,19 @@ print_frame (PyObject *filter, int print_level,
if (result)
{
char *dup = PyString_AsString (result);
- if (dup)
- filename = xstrdup (dup);
- else
- return 0;
+
+ if (! dup)
+ {
+ Py_DECREF (result);
+ goto error;
+ }
+
+ filename = xstrdup (dup);
+
Py_DECREF (result);
}
+ else
+ goto error;
}
else
func = xstrdup("<unknown function>");
@@ -357,6 +408,8 @@ print_frame (PyObject *filter, int print_level,
line = PyLong_AsLong (result);
Py_DECREF (result);
}
+ else
+ goto error;
}
else
line = 0;
@@ -369,10 +422,55 @@ print_frame (PyObject *filter, int print_level,
ui_out_text (out, "\n");
annotate_frame_end ();
+ if (PyObject_HasAttrString (filter, "elide"))
+ {
+ PyObject *result = PyObject_CallMethod (filter, "elide", NULL);
+
+ if (result)
+ {
+ struct frame_info *restart = NULL;
+ struct frame_info *current = NULL;
+ /* Fix result here. */
+ TRY_CATCH (except, RETURN_MASK_ALL)
+ {
+ restart = frame_object_to_frame_info (result);
+ }
+ if (except.reason > 0)
+ {
+ Py_DECREF (result);
+ PyErr_SetString (PyExc_RuntimeError,
+ except.message);
+ goto error;
+ }
+ if (! restart)
+ {
+ Py_DECREF (result);
+ PyErr_SetString (PyExc_RuntimeError,
+ _("Cannot locate frame to continue backtrace."));
+ goto error;
+ }
+ if (restart != frame)
+ {
+ current=get_prev_frame (frame);
+ while (current!=restart)
+ {
+ set_frame_print_elide (current);
+ current = get_prev_frame (current);
+ }
+ }
+ }
+ else
+ goto error;
+ }
+
xfree (func);
xfree (filename);
-
return 1;
+
+ error:
+ xfree (func);
+ xfree (filename);
+ return 0;
}
int
@@ -386,6 +484,7 @@ apply_frame_filter (struct frame_info *frame, int print_level,
int result = 0;
int print_result = 0;
struct value_print_options opts;
+ int success = 0;
cleanups = ensure_python_env (gdbarch, current_language);
@@ -396,32 +495,34 @@ apply_frame_filter (struct frame_info *frame, int print_level,
/* Find the constructor. */
filter = find_frame_filter (frame_obj, print_level, print_what, print_args);
Py_DECREF (frame_obj);
+
make_cleanup_py_decref (filter);
if (! filter || filter == Py_None)
goto done;
get_user_print_options (&opts);
- print_result = print_frame (filter, print_level, print_what,
- print_args, out, opts, frame);
+ success = print_frame (filter, print_level, print_what,
+ print_args, out, opts, frame);
- if (print_result)
- result = 1;
- else
+ /* '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 ();
done:
do_cleanups (cleanups);
- return result;
+ return success;
}
#else /* HAVE_PYTHON */
-int
+struct frame_info *
apply_frame_filter (struct frame_info *frame, int print_level,
enum print_what print_what, int print_args,
struct ui_out *out)
{
- return 0;
+ return NULL;
}
#endif /* HAVE_PYTHON */
diff --git a/gdb/python/python.h b/gdb/python/python.h
index 0344aa9..32a5653 100644
--- a/gdb/python/python.h
+++ b/gdb/python/python.h
@@ -39,8 +39,10 @@ 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,
- enum print_what print_what, int print_args,
+int apply_frame_filter (struct frame_info *frame,
+ int print_level,
+ enum print_what print_what,
+ int print_args,
struct ui_out *out);
void preserve_python_values (struct objfile *objfile, htab_t copied_types);
diff --git a/gdb/stack.c b/gdb/stack.c
index bdd63f4..9ae4290 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -762,12 +762,17 @@ print_frame_info (struct frame_info *frame, int print_level,
struct symtab_and_line sal;
int source_print;
int location_print;
- int result;
struct ui_out *uiout = current_uiout;
- result = apply_frame_filter (frame, 1, LOCATION, 1, current_uiout);
- if (result)
- return;
+ /* If a previous frame elided this one, do not run the frame
+ filters. */
+ if (! frame_print_elide (frame))
+ {
+ int result = apply_frame_filter (frame, 1, LOCATION, 1,
+ current_uiout);
+ if (result)
+ return;
+ }
if (get_frame_type (frame) == DUMMY_FRAME
|| get_frame_type (frame) == SIGTRAMP_FRAME
@@ -783,7 +788,7 @@ print_frame_info (struct frame_info *frame, int print_level,
to list for this frame. */
if (print_level)
{
- ui_out_text (uiout, "#");
+ ui_out_text (uiout, "#");
ui_out_field_fmt_int (uiout, 2, ui_left, "level",
frame_relative_level (frame));
}
@@ -1128,6 +1133,9 @@ print_frame (struct frame_info *frame, int print_level,
list_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "frame");
+ if (frame_print_elide (frame))
+ ui_out_spaces (uiout, 4);
+
if (print_level)
{
ui_out_text (uiout, "#");
diff --git a/gdb/testsuite/gdb.python/py-framefilter.c b/gdb/testsuite/gdb.python/py-framefilter.c
index 26f561f..6113716 100644
--- a/gdb/testsuite/gdb.python/py-framefilter.c
+++ b/gdb/testsuite/gdb.python/py-framefilter.c
@@ -37,7 +37,7 @@ void funca(void)
count++;
funcb(count);
}
-
+
end_func();
return;
}
@@ -83,4 +83,3 @@ main()
{
func5(3);
}
-
diff --git a/gdb/testsuite/gdb.python/py-framefilter.exp b/gdb/testsuite/gdb.python/py-framefilter.exp
index 73c1ba5..a3b1126 100644
--- a/gdb/testsuite/gdb.python/py-framefilter.exp
+++ b/gdb/testsuite/gdb.python/py-framefilter.exp
@@ -40,6 +40,6 @@ set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py]
gdb_test_no_output "python execfile ('${remote_python_file}')"
gdb_test_no_output "python gdb.frame_filters.append(register_frame_filters)"
gdb_breakpoint [gdb_get_line_number "Backtrace end breakpoint"]
-gdb_continue_to_breakpoint "Bactrace end breakpoint"
-gdb_test "bt" "#1.*in end_func.*#23.*in func1.*#27.*in main ().*"
+gdb_continue_to_breakpoint "Backtrace end breakpoint"
+gdb_test "bt" "#0.*in end_func.*#22.*in func1.*Composite frame func3.*#27.*in main ().*"
remote_file host delete ${remote_python_file}
diff --git a/gdb/testsuite/gdb.python/py-framefilter.py b/gdb/testsuite/gdb.python/py-framefilter.py
index b7ee5c5..a3afe1a 100644
--- a/gdb/testsuite/gdb.python/py-framefilter.py
+++ b/gdb/testsuite/gdb.python/py-framefilter.py
@@ -16,8 +16,6 @@
# This file is part of the GDB testsuite. It tests Python-based
# frame-filters.
-flevel = 0
-
class Main_filter:
"Example main () filter"
@@ -26,16 +24,34 @@ class Main_filter:
self.what = what
self.lvl = level
self.args = args
-
+
+ def omit (self):
+ fname = str (self.frame.function())
+ if fname == "func2":
+ return True
+ else:
+ return False
+
+ def elide (self):
+ fname = str (self.frame.function())
+ frame = self.frame
+
+ if fname == "func3":
+ frame = frame.older()
+ frame = frame.older()
+ frame = frame.older()
+
+ return frame
def function (self):
- return str (self.frame.function())
+ fname = str (self.frame.function())
+ if fname == "func3":
+ return "Composite frame " + str(self.frame.function())
+ else:
+ return str (self.frame.function())
- def level (self):
- global flevel
- rlevel = flevel
- flevel = flevel + 1
- return rlevel
+ def level (self, level):
+ return level
def address (self):
return self.frame.pc()
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2012-03-19 15:06 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-19 15:06 [SCM] archer-pmuldoon-python-backtrace: Implement omit and (bogus, non duck typed) elide function 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).