public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] archer-pmuldoon-python-breakpoints: First initial draft of python conditional evaluation.
@ 2010-11-12 14:22 pmuldoon
0 siblings, 0 replies; only message in thread
From: pmuldoon @ 2010-11-12 14:22 UTC (permalink / raw)
To: archer-commits
The branch, archer-pmuldoon-python-breakpoints has been updated
via 84d75e8311a875434bde397c4ab5229b0d101609 (commit)
from 85f67c7e591d0bedce08442ee0bba726b002e509 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit 84d75e8311a875434bde397c4ab5229b0d101609
Author: Phil Muldoon <pmuldoon@redhat.com>
Date: Fri Nov 12 14:21:57 2010 +0000
First initial draft of python conditional evaluation.
-----------------------------------------------------------------------
Summary of changes:
gdb/breakpoint.c | 190 ++++++++++++++++++++++++++------------------
gdb/breakpoint.h | 7 ++
gdb/python/py-breakpoint.c | 2 +-
3 files changed, 122 insertions(+), 77 deletions(-)
First 500 lines of diff:
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 6b55313..6c49569 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -244,7 +244,7 @@ breakpoint_commands (struct breakpoint *b)
/* Flag indicating that a command has proceeded the inferior past the
current breakpoint. */
-static int breakpoint_proceeded;
+int breakpoint_proceeded;
static const char *
bpdisp_text (enum bpdisp disp)
@@ -2997,7 +2997,7 @@ bpstat_clear_actions (bpstat bs)
/* Called when a command is about to proceed the inferior. */
-static void
+void
breakpoint_about_to_proceed (void)
{
if (!ptid_equal (inferior_ptid, null_ptid))
@@ -3909,7 +3909,7 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
int thread_id = pid_to_thread_id (ptid);
const struct bp_location *bl;
struct breakpoint *b;
-
+ int python_condition_sprung = 0;
/* BS is built for existing struct breakpoint. */
bl = bs->bp_location_at;
gdb_assert (bl != NULL);
@@ -3924,88 +3924,126 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
int value_is_zero = 0;
struct expression *cond;
- if (is_watchpoint (b))
- cond = b->cond_exp;
- else
- cond = bl->cond;
+ /* TODO: Put the Python case here for now. Not sure what happens when a
+ breakpoint has a condition and a python eval function. I guess stop
+ if either become true. */
+#if HAVE_PYTHON
+ PyGILState_STATE state;
+ PyObject *gdbpy_bp_eval = PyString_FromString ("eval");
+ int evaluate = 0;
+ PyObject *result;
+
+ state = PyGILState_Ensure ();
+
+ if (b->py_bp_object)
+ {
+ if (PyObject_HasAttr (b->py_bp_object, gdbpy_bp_eval))
+ {
+ result = PyObject_CallMethodObjArgs (b->py_bp_object, gdbpy_bp_eval, NULL);
+ if (result)
+ {
+ evaluate = PyObject_IsTrue (result);
+ if (evaluate == -1)
+ error( _("Error while evaluating breakpoint function."));
+
+ if (evaluate)
+ bs->stop = 1;
+ else
+ bs->stop = 0;
+
+ python_condition_sprung = 1;
+ }
+ }
+ }
+
+ PyGILState_Release (state);
+#endif
- if (cond && b->disposition != disp_del_at_next_stop)
+ if (!python_condition_sprung)
{
- int within_current_scope = 1;
-
- /* We use value_mark and value_free_to_mark because it could
- be a long time before we return to the command level and
- call free_all_values. We can't call free_all_values
- because we might be in the middle of evaluating a
- function call. */
- struct value *mark = value_mark ();
-
- /* Need to select the frame, with all that implies so that
- the conditions will have the right context. Because we
- use the frame, we will not see an inlined function's
- variables when we arrive at a breakpoint at the start
- of the inlined function; the current frame will be the
- call site. */
- if (!is_watchpoint (b) || b->cond_exp_valid_block == NULL)
- select_frame (get_current_frame ());
+ if (is_watchpoint (b))
+ cond = b->cond_exp;
else
+ cond = bl->cond;
+
+ if (cond && b->disposition != disp_del_at_next_stop)
{
- struct frame_info *frame;
-
- /* For local watchpoint expressions, which particular
- instance of a local is being watched matters, so we
- keep track of the frame to evaluate the expression
- in. To evaluate the condition however, it doesn't
- really matter which instantiation of the function
- where the condition makes sense triggers the
- watchpoint. This allows an expression like "watch
- global if q > 10" set in `func', catch writes to
- global on all threads that call `func', or catch
- writes on all recursive calls of `func' by a single
- thread. We simply always evaluate the condition in
- the innermost frame that's executing where it makes
- sense to evaluate the condition. It seems
- intuitive. */
- frame = block_innermost_frame (b->cond_exp_valid_block);
- if (frame != NULL)
- select_frame (frame);
+ int within_current_scope = 1;
+
+ /* We use value_mark and value_free_to_mark because it could
+ be a long time before we return to the command level and
+ call free_all_values. We can't call free_all_values
+ because we might be in the middle of evaluating a
+ function call. */
+ struct value *mark = value_mark ();
+
+ /* Need to select the frame, with all that implies so that
+ the conditions will have the right context. Because we
+ use the frame, we will not see an inlined function's
+ variables when we arrive at a breakpoint at the start
+ of the inlined function; the current frame will be the
+ call site. */
+ if (!is_watchpoint (b) || b->cond_exp_valid_block == NULL)
+ select_frame (get_current_frame ());
else
- within_current_scope = 0;
+ {
+ struct frame_info *frame;
+
+ /* For local watchpoint expressions, which particular
+ instance of a local is being watched matters, so we
+ keep track of the frame to evaluate the expression
+ in. To evaluate the condition however, it doesn't
+ really matter which instantiation of the function
+ where the condition makes sense triggers the
+ watchpoint. This allows an expression like "watch
+ global if q > 10" set in `func', catch writes to
+ global on all threads that call `func', or catch
+ writes on all recursive calls of `func' by a single
+ thread. We simply always evaluate the condition in
+ the innermost frame that's executing where it makes
+ sense to evaluate the condition. It seems
+ intuitive. */
+ frame = block_innermost_frame (b->cond_exp_valid_block);
+ if (frame != NULL)
+ select_frame (frame);
+ else
+ within_current_scope = 0;
+ }
+ if (within_current_scope)
+ value_is_zero
+ = catch_errors (breakpoint_cond_eval, cond,
+ "Error in testing breakpoint condition:\n",
+ RETURN_MASK_ALL);
+ else
+ {
+ warning (_("Watchpoint condition cannot be tested "
+ "in the current scope"));
+ /* If we failed to set the right context for this
+ watchpoint, unconditionally report it. */
+ value_is_zero = 0;
+ }
+ /* FIXME-someday, should give breakpoint # */
+ value_free_to_mark (mark);
}
- if (within_current_scope)
- value_is_zero
- = catch_errors (breakpoint_cond_eval, cond,
- "Error in testing breakpoint condition:\n",
- RETURN_MASK_ALL);
- else
+
+ if (cond && value_is_zero)
{
- warning (_("Watchpoint condition cannot be tested "
- "in the current scope"));
- /* If we failed to set the right context for this
- watchpoint, unconditionally report it. */
- value_is_zero = 0;
+ bs->stop = 0;
}
- /* FIXME-someday, should give breakpoint # */
- value_free_to_mark (mark);
- }
-
- if (cond && value_is_zero)
- {
- bs->stop = 0;
- }
- else if (b->thread != -1 && b->thread != thread_id)
- {
- bs->stop = 0;
+ else if (b->thread != -1 && b->thread != thread_id)
+ {
+ bs->stop = 0;
+ }
+ else if (b->ignore_count > 0)
+ {
+ b->ignore_count--;
+ annotate_ignore_count_change ();
+ bs->stop = 0;
+ /* Increase the hit count even though we don't
+ stop. */
+ ++(b->hit_count);
+ }
}
- else if (b->ignore_count > 0)
- {
- b->ignore_count--;
- annotate_ignore_count_change ();
- bs->stop = 0;
- /* Increase the hit count even though we don't
- stop. */
- ++(b->hit_count);
- }
}
}
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index e34c2d3..48a344f 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -32,6 +32,11 @@
struct value;
struct block;
+/* Flag indicating that a command has proceeded the inferior past the
+ current breakpoint. */
+
+int breakpoint_proceeded;
+
/* This is the maximum number of bytes a breakpoint instruction can take.
Feel free to increase it. It's just used in a few places to size
arrays that should be independent of the target architecture. */
@@ -1125,4 +1130,6 @@ extern void end_rbreak_breakpoints (void);
extern struct breakpoint *iterate_over_breakpoints (int (*) (struct breakpoint *,
void *), void *);
+extern void breakpoint_about_to_proceed (void);
+
#endif /* !defined (BREAKPOINT_H) */
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index 8afa414..23a0de4 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -868,7 +868,7 @@ static PyTypeObject breakpoint_object_type =
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"GDB breakpoint object", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2010-11-12 14:22 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-12 14:22 [SCM] archer-pmuldoon-python-breakpoints: First initial draft of python conditional evaluation 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).