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).