[Lldb-commits] [lldb] r116542 - in /lldb/trunk: include/lldb/Breakpoint/ include/lldb/Core/ include/lldb/Expression/ include/lldb/Target/ lldb.xcodeproj/ source/Breakpoint/ source/Commands/ source/Core/ source/Expression/ source/Target/

Jim Ingham jingham at apple.com
Thu Oct 14 16:45:03 PDT 2010


Author: jingham
Date: Thu Oct 14 18:45:03 2010
New Revision: 116542

URL: http://llvm.org/viewvc/llvm-project?rev=116542&view=rev
Log:
Added support for breakpoint conditions.  I also had to separate the "run the expression" part of ClangFunction::Execute from the "Gather the expression result" so that in the case of the Breakpoint condition I can move the condition evaluation into the normal thread plan processing.

Also added support for remembering the "last set breakpoint" so that "break modify" will act on the last set breakpoint.

Added:
    lldb/trunk/include/lldb/Target/ThreadPlanTestCondition.h
    lldb/trunk/source/Target/ThreadPlanTestCondition.cpp
Modified:
    lldb/trunk/include/lldb/Breakpoint/Breakpoint.h
    lldb/trunk/include/lldb/Breakpoint/BreakpointLocation.h
    lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h
    lldb/trunk/include/lldb/Core/Event.h
    lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h
    lldb/trunk/include/lldb/Expression/ClangUserExpression.h
    lldb/trunk/include/lldb/Target/Process.h
    lldb/trunk/include/lldb/Target/StopInfo.h
    lldb/trunk/include/lldb/Target/Target.h
    lldb/trunk/include/lldb/Target/Thread.h
    lldb/trunk/include/lldb/Target/ThreadPlan.h
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Breakpoint/Breakpoint.cpp
    lldb/trunk/source/Breakpoint/BreakpointLocation.cpp
    lldb/trunk/source/Breakpoint/BreakpointOptions.cpp
    lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp
    lldb/trunk/source/Commands/CommandObjectBreakpoint.h
    lldb/trunk/source/Core/Event.cpp
    lldb/trunk/source/Expression/ClangExpressionParser.cpp
    lldb/trunk/source/Expression/ClangFunction.cpp
    lldb/trunk/source/Expression/ClangUserExpression.cpp
    lldb/trunk/source/Target/Process.cpp
    lldb/trunk/source/Target/StopInfo.cpp
    lldb/trunk/source/Target/Target.cpp

Modified: lldb/trunk/include/lldb/Breakpoint/Breakpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/Breakpoint.h?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/Breakpoint.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/Breakpoint.h Thu Oct 14 18:45:03 2010
@@ -370,12 +370,41 @@
     ClearCallback ();
 
     //------------------------------------------------------------------
-    /// Set the condition expression to be checked when the breakpoint is hit.
-    /// @param[in] expression
-    ///    The method that will get called when the breakpoint is hit.
+    /// Set the breakpoint's condition.
+    ///
+    /// @param[in] condition
+    ///    The condition expression to evaluate when the breakpoint is hit.
+    ///    Pass in NULL to clear the condition.
     //------------------------------------------------------------------
-    void
-    SetCondition (void *expression);
+    void SetCondition (const char *condition);
+    
+    //------------------------------------------------------------------
+    /// Test the breakpoint condition in the Execution context passed in.
+    ///
+    /// @param[in] exe_ctx
+    ///    The execution context in which to evaluate this expression.
+    /// 
+    /// @param[in] break_loc_sp
+    ///    A shared pointer to the location that we are testing thsi condition for.
+    ///
+    /// @param[in] error
+    ///    Error messages will be written to this stream.
+    ///
+    /// @return
+    ///     A thread plan to run to test the condition or NULL if no condition.
+    //------------------------------------------------------------------
+    ThreadPlan *GetThreadPlanToTestCondition (ExecutionContext &exe_ctx, 
+                                              lldb::BreakpointLocationSP break_loc_sp, 
+                                              Stream &error);
+    
+    //------------------------------------------------------------------
+    /// Return a pointer to the text of the condition expression.
+    ///
+    /// @return
+    ///    A pointer to the condition expression text, or NULL if no
+    //     condition has been set.
+    //------------------------------------------------------------------
+    const char *GetConditionText ();
 
     //------------------------------------------------------------------
     // The next section are various utility functions.

Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointLocation.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointLocation.h?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/BreakpointLocation.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointLocation.h Thu Oct 14 18:45:03 2010
@@ -160,13 +160,35 @@
     ClearCallback ();
 
     //------------------------------------------------------------------
-    /// Set the condition expression to be checked when the breakpoint is hit.
+    /// Set the breakpoint location's condition.
     ///
-    /// @param[in] expression
-    ///    The method that will get called when the breakpoint is hit.
+    /// @param[in] condition
+    ///    The condition expression to evaluate when the breakpoint is hit.
     //------------------------------------------------------------------
-    void
-    SetCondition (void *condition);
+    void SetCondition (const char *condition);
+    
+    //------------------------------------------------------------------
+    /// Test the breakpoint location's condition in the Execution context passed in.
+    ///
+    /// @param[in] exe_ctx
+    ///    The execution context in which to evaluate this expression.
+    /// 
+    /// @param[in] error
+    ///    Error messages will be written to this stream.
+    ///
+    /// @return
+    ///     A thread plan to run to test the condition, or NULL if there is no condition.
+    //------------------------------------------------------------------
+    ThreadPlan *GetThreadPlanToTestCondition (ExecutionContext &exe_ctx, Stream &error);
+    
+    //------------------------------------------------------------------
+    /// Return a pointer to the text of the condition expression.
+    ///
+    /// @return
+    ///    A pointer to the condition expression text, or NULL if no
+    //     condition has been set.
+    //------------------------------------------------------------------
+    const char *GetConditionText ();
 
 
     //------------------------------------------------------------------
@@ -211,6 +233,9 @@
     //------------------------------------------------------------------
     bool
     IsResolved () const;
+    
+    lldb::BreakpointSiteSP
+    GetBreakpointSite() const;
 
     //------------------------------------------------------------------
     // The next section are generic report functions.

Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h Thu Oct 14 18:45:03 2010
@@ -18,6 +18,7 @@
 #include "lldb/lldb-private.h"
 #include "lldb/Core/Baton.h"
 #include "lldb/Core/StringList.h"
+#include "lldb/Expression/ClangUserExpression.h"
 
 namespace lldb_private {
 
@@ -88,7 +89,46 @@
     Baton *GetBaton ();
     const Baton *GetBaton () const;
     void ClearCallback ();
-
+    
+    //------------------------------------------------------------------
+    // Condition
+    //------------------------------------------------------------------
+    //------------------------------------------------------------------
+    /// Set the breakpoint option's condition.
+    ///
+    /// @param[in] condition
+    ///    The condition expression to evaluate when the breakpoint is hit.
+    //------------------------------------------------------------------
+    void SetCondition (const char *condition);
+    
+    //------------------------------------------------------------------
+    /// Test the breakpoint condition in the Execution context passed in.
+    ///
+    /// @param[in] exe_ctx
+    ///    The execution context in which to evaluate this expression.
+    /// 
+    /// @param[in] break_loc_sp
+    ///    A shared pointer to the location that we are testing thsi condition for.
+    ///
+    /// @param[in] error
+    ///    Error messages will be written to this stream.
+    ///
+    /// @return
+    ///     A thread plan to run to test the condition, or NULL if there is no thread plan.
+    //------------------------------------------------------------------
+    ThreadPlan *GetThreadPlanToTestCondition (ExecutionContext &exe_ctx, 
+                                              lldb::BreakpointLocationSP break_loc_sp, 
+                                              Stream &error);
+    
+    //------------------------------------------------------------------
+    /// Return a pointer to the text of the condition expression.
+    ///
+    /// @return
+    ///    A pointer to the condition expression text, or NULL if no
+    //     condition has been set.
+    //------------------------------------------------------------------
+    const char *GetConditionText ();
+    
     //------------------------------------------------------------------
     // Enabled/Ignore Count
     //------------------------------------------------------------------
@@ -107,6 +147,12 @@
     void
     SetEnabled (bool enabled);
 
+    //------------------------------------------------------------------
+    /// Set the breakpoint to ignore the next \a count breakpoint hits.
+    /// @param[in] count
+    ///    The number of breakpoint hits to ignore.
+    //------------------------------------------------------------------
+
     void
     SetIgnoreCount (uint32_t n);
 
@@ -119,12 +165,6 @@
     GetIgnoreCount () const;
 
     //------------------------------------------------------------------
-    /// Set the breakpoint to ignore the next \a count breakpoint hits.
-    /// @param[in] count
-    ///    The number of breakpoint hits to ignore.
-    //------------------------------------------------------------------
-
-    //------------------------------------------------------------------
     /// Return the current thread spec for this option.  This will return NULL if the no thread
     /// specifications have been set for this Option yet.     
     /// @return
@@ -218,6 +258,7 @@
     bool m_enabled;
     uint32_t m_ignore_count; // Number of times to ignore this breakpoint
     std::auto_ptr<ThreadSpec> m_thread_spec_ap; // Thread for which this breakpoint will take
+    std::auto_ptr<ClangUserExpression> m_condition_ap;  // The condition to test.
 
 };
 

Modified: lldb/trunk/include/lldb/Core/Event.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Event.h?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Event.h (original)
+++ lldb/trunk/include/lldb/Core/Event.h Thu Oct 14 18:45:03 2010
@@ -134,22 +134,52 @@
     Dump (Stream *s) const;
 
     EventData *
-    GetData ();
+    GetData ()
+    {
+        return m_data_ap.get();
+    }
 
     const EventData *
-    GetData () const;
+    GetData () const
+    {
+        return m_data_ap.get();
+    }
+    
+    void
+    SetData (EventData *new_data)
+    {
+        m_data_ap.reset (new_data);
+    }
 
     uint32_t
-    GetType () const;
+    GetType () const
+    {
+        return m_type;
+    }
+    
+    void
+    SetType (uint32_t new_type)
+    {
+        m_type = new_type;
+    }
 
     Broadcaster *
-    GetBroadcaster () const;
-
+    GetBroadcaster () const
+    {
+        return m_broadcaster;
+    }
+    
     bool
-    BroadcasterIs (Broadcaster *broadcaster);
+    BroadcasterIs (Broadcaster *broadcaster)
+    {
+        return broadcaster == m_broadcaster;
+    }
 
     void
-    Clear();
+    Clear()
+    {
+        m_data_ap.reset();
+    }
 
 
 private:
@@ -164,7 +194,11 @@
     // know about it update the contained broadcaster so that events can be
     // popped off one queue and re-broadcast to others.
     void
-    SetBroadcaster (Broadcaster *broadcaster);
+    SetBroadcaster (Broadcaster *broadcaster)
+    {
+        m_broadcaster = broadcaster;
+    }
+
 
     Broadcaster *   m_broadcaster;  // The broadcaster that sent this event
     uint32_t        m_type;         // The bit describing this event

Modified: lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h Thu Oct 14 18:45:03 2010
@@ -89,7 +89,8 @@
     /// The following values should stay valid for the life of the variable
     //----------------------------------------------------------------------
     std::string             m_name;         ///< The name of the variable
-    TypeFromUser            m_user_type;    ///< The type of the variable according to some LLDB context; NULL if the type hasn't yet been migrated to one
+    TypeFromUser            m_user_type;    ///< The type of the variable according to some LLDB context; 
+                                            ///< NULL if the type hasn't yet been migrated to one
     
     //----------------------------------------------------------------------
     /// The following values indicate where the variable originally came from

Modified: lldb/trunk/include/lldb/Expression/ClangUserExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangUserExpression.h?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ClangUserExpression.h (original)
+++ lldb/trunk/include/lldb/Expression/ClangUserExpression.h Thu Oct 14 18:45:03 2010
@@ -24,6 +24,7 @@
 #include "lldb/lldb-private.h"
 #include "lldb/Core/ClangForward.h"
 #include "lldb/Expression/ClangExpression.h"
+#include "lldb/Expression/ClangExpressionVariable.h"
 
 #include "llvm/ExecutionEngine/JITMemoryManager.h"
 
@@ -90,7 +91,15 @@
     bool
     Execute (Stream &error_stream,
              ExecutionContext &exe_ctx,
-             ClangExpressionVariable *& result);
+             ClangExpressionVariable *&result);
+             
+    ThreadPlan *
+    GetThreadPlanToExecuteJITExpression (Stream &error_stream,
+                                 ExecutionContext &exe_ctx);
+    bool
+    FinalizeJITExecution (Stream &error_stream,
+                        ExecutionContext &exe_ctx,
+                        ClangExpressionVariable *&result);
     
     //------------------------------------------------------------------
     /// Return the string that the parser should parse.  Must be a full
@@ -103,6 +112,15 @@
     }
     
     //------------------------------------------------------------------
+    /// Return the string that the user typed.
+    //------------------------------------------------------------------
+    const char *
+    GetUserText ()
+    {
+        return m_expr_text.c_str();
+    }
+    
+    //------------------------------------------------------------------
     /// Return the function name that should be used for executing the
     /// expression.  Text() should contain the definition of this
     /// function.
@@ -181,6 +199,12 @@
     //------------------------------------------------------------------
     void
     ScanContext(ExecutionContext &exe_ctx);
+
+    bool
+    PrepareToExecuteJITExpression (Stream &error_stream,
+                                       ExecutionContext &exe_ctx,
+                                       lldb::addr_t &struct_address,
+                                       lldb::addr_t object_ptr);
     
     std::string                                 m_expr_text;            ///< The text of the expression, as typed by the user
     std::string                                 m_transformed_text;     ///< The text of the expression, as send to the parser

Modified: lldb/trunk/include/lldb/Target/Process.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Process.h (original)
+++ lldb/trunk/include/lldb/Target/Process.h Thu Oct 14 18:45:03 2010
@@ -232,6 +232,7 @@
     public ProcessInstanceSettings
 {
 friend class ThreadList;
+friend class ClangFunction; // For WaitForStateChangeEventsPrivate
 
 public:
 
@@ -316,7 +317,6 @@
             static bool
             SetUpdateStateOnRemoval (Event *event_ptr);
 
-
        private:
 
             void
@@ -1592,12 +1592,12 @@
     
     DynamicCheckerFunctions *GetDynamicCheckers()
     {
-        return m_dynamic_checkers.get();
+        return m_dynamic_checkers_ap.get();
     }
     
     void SetDynamicCheckers(DynamicCheckerFunctions *dynamic_checkers)
     {
-        m_dynamic_checkers.reset(dynamic_checkers);
+        m_dynamic_checkers_ap.reset(dynamic_checkers);
     }
 
     //------------------------------------------------------------------
@@ -1646,7 +1646,7 @@
     BreakpointSiteList          m_breakpoint_site_list; ///< This is the list of breakpoint locations we intend
                                                         ///< to insert in the target.
     ClangPersistentVariables    m_persistent_vars;      ///< These are the persistent variables associated with this process for the expression parser.
-    std::auto_ptr<DynamicCheckerFunctions>  m_dynamic_checkers; ///< The functions used by the expression parser to validate data that expressions use.
+    std::auto_ptr<DynamicCheckerFunctions>  m_dynamic_checkers_ap; ///< The functions used by the expression parser to validate data that expressions use.
     UnixSignals                 m_unix_signals;         /// This is the current signal set for this process.
     ConstString                 m_target_triple;
     lldb::ABISP                 m_abi_sp;

Modified: lldb/trunk/include/lldb/Target/StopInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StopInfo.h?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/StopInfo.h (original)
+++ lldb/trunk/include/lldb/Target/StopInfo.h Thu Oct 14 18:45:03 2010
@@ -90,6 +90,10 @@
     static lldb::StopInfoSP
     CreateStopReasonWithBreakpointSiteID (Thread &thread, lldb::break_id_t break_id);
 
+    // This creates a StopInfo for the thread where the should_stop is already set, and won't be recalculated.
+    static lldb::StopInfoSP
+    CreateStopReasonWithBreakpointSiteID (Thread &thread, lldb::break_id_t break_id, bool should_stop);
+
     static lldb::StopInfoSP
     CreateStopReasonWithWatchpointID (Thread &thread, lldb::break_id_t watch_id);
 

Modified: lldb/trunk/include/lldb/Target/Target.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Thu Oct 14 18:45:03 2010
@@ -204,6 +204,12 @@
 
     const BreakpointList &
     GetBreakpointList(bool internal = false) const;
+    
+    lldb::BreakpointSP
+    GetLastCreatedBreakpoint ()
+    {
+        return m_last_created_breakpoint;
+    }
 
     lldb::BreakpointSP
     GetBreakpointByID (lldb::break_id_t break_id);
@@ -443,6 +449,7 @@
     SectionLoadList m_section_load_list;
     BreakpointList  m_breakpoint_list;
     BreakpointList  m_internal_breakpoint_list;
+    lldb::BreakpointSP m_last_created_breakpoint;
     // We want to tightly control the process destruction process so
     // we can correctly tear down everything that we need to, so the only
     // class that knows about the process lifespan is this target class.

Modified: lldb/trunk/include/lldb/Target/Thread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Thread.h (original)
+++ lldb/trunk/include/lldb/Target/Thread.h Thu Oct 14 18:45:03 2010
@@ -238,6 +238,12 @@
     StopInfo *
     GetStopInfo ();
 
+    void
+    SetStopInfo (lldb::StopInfoSP stop_info_sp)
+    {
+        m_public_stop_info_sp = stop_info_sp;
+    }
+
     bool
     ThreadStoppedForAReason ();
 

Modified: lldb/trunk/include/lldb/Target/ThreadPlan.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlan.h?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlan.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadPlan.h Thu Oct 14 18:45:03 2010
@@ -179,6 +179,8 @@
         eThisThread
     } ThreadScope;
 
+    // We use these enums so that we can cast a base thread plan to it's real type without having to resort
+    // to dynamic casting.
     typedef enum
     {
         eKindGeneric,
@@ -191,7 +193,8 @@
         eKindStepInRange,
         eKindRunToAddress,
         eKindStepThrough,
-        eKindStepUntil
+        eKindStepUntil,
+        eKindTestCondition
         
     } ThreadPlanKind;
     

Added: lldb/trunk/include/lldb/Target/ThreadPlanTestCondition.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadPlanTestCondition.h?rev=116542&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadPlanTestCondition.h (added)
+++ lldb/trunk/include/lldb/Target/ThreadPlanTestCondition.h Thu Oct 14 18:45:03 2010
@@ -0,0 +1,65 @@
+//===-- ThreadPlanTestCondition.h -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ThreadPlanTestCondition_h_
+#define liblldb_ThreadPlanTestCondition_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/AddressRange.h"
+#include "lldb/Target/ExecutionContext.h"
+#include "lldb/Expression/ClangUserExpression.h"
+#include "lldb/Target/StackID.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/ThreadPlanShouldStopHere.h"
+
+namespace lldb_private {
+
+class ThreadPlanTestCondition : public ThreadPlan
+{
+public:
+    virtual ~ThreadPlanTestCondition ();
+
+    ThreadPlanTestCondition (Thread &thread,
+                         ExecutionContext &exe_ctx,
+                         ClangUserExpression *expression,
+                         lldb::BreakpointLocationSP break_loc_sp,
+                         bool stop_others);
+                         
+    virtual void GetDescription (Stream *s, lldb::DescriptionLevel level);
+    virtual bool ValidatePlan (Stream *error);
+    virtual bool PlanExplainsStop ();
+    virtual bool ShouldStop (Event *event_ptr);
+    virtual lldb::Vote ShouldReportStop (Event *event_ptr);
+    virtual bool StopOthers ();
+    virtual lldb::StateType RunState ();
+    virtual bool WillStop ();
+    virtual bool MischiefManaged ();
+    virtual void DidPush ();
+
+protected:
+
+private:
+    ClangUserExpression *m_expression;
+    ExecutionContext m_exe_ctx;
+    lldb::ThreadPlanSP m_expression_plan_sp;
+    lldb::BreakpointLocationSP m_break_loc_sp;
+    bool m_did_stop;
+    bool m_stop_others;
+    
+    DISALLOW_COPY_AND_ASSIGN (ThreadPlanTestCondition);
+
+};
+
+} // namespace lldb_private
+
+#endif  // liblldb_ThreadPlanTestCondition_h_

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Thu Oct 14 18:45:03 2010
@@ -356,6 +356,8 @@
 		4C0A91DB12511CB900CA6636 /* AppleThreadPlanStepThroughObjCTrampoline.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C0A91D712511CB900CA6636 /* AppleThreadPlanStepThroughObjCTrampoline.h */; };
 		4C139EA5124A8B03000BFF8D /* AppleObjCRuntimeV2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C139EA3124A8B03000BFF8D /* AppleObjCRuntimeV2.cpp */; };
 		4C139EA6124A8B03000BFF8D /* AppleObjCRuntimeV2.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C139EA4124A8B03000BFF8D /* AppleObjCRuntimeV2.h */; };
+		4C1AB23B1263E5F400D0F04A /* ThreadPlanTestCondition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C1AB23A1263E5F400D0F04A /* ThreadPlanTestCondition.cpp */; };
+		4C1AB23F1263E61100D0F04A /* ThreadPlanTestCondition.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1AB23E1263E61100D0F04A /* ThreadPlanTestCondition.h */; };
 		4C5DBBC811E3FEC60035160F /* CommandObjectCommands.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C5DBBC611E3FEC60035160F /* CommandObjectCommands.cpp */; };
 		4C5DBBC911E3FEC60035160F /* CommandObjectCommands.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C5DBBC711E3FEC60035160F /* CommandObjectCommands.h */; };
 		4C74CB6312288704006A8171 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C74CB6212288704006A8171 /* Carbon.framework */; };
@@ -980,6 +982,8 @@
 		4C0A91D712511CB900CA6636 /* AppleThreadPlanStepThroughObjCTrampoline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppleThreadPlanStepThroughObjCTrampoline.h; path = LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleThreadPlanStepThroughObjCTrampoline.h; sourceTree = "<group>"; };
 		4C139EA3124A8B03000BFF8D /* AppleObjCRuntimeV2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AppleObjCRuntimeV2.cpp; path = LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.cpp; sourceTree = "<group>"; };
 		4C139EA4124A8B03000BFF8D /* AppleObjCRuntimeV2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppleObjCRuntimeV2.h; path = LanguageRuntime/ObjC/AppleObjCRuntimeV2/AppleObjCRuntimeV2.h; sourceTree = "<group>"; };
+		4C1AB23A1263E5F400D0F04A /* ThreadPlanTestCondition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanTestCondition.cpp; path = source/Target/ThreadPlanTestCondition.cpp; sourceTree = "<group>"; };
+		4C1AB23E1263E61100D0F04A /* ThreadPlanTestCondition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanTestCondition.h; path = include/lldb/Target/ThreadPlanTestCondition.h; sourceTree = "<group>"; };
 		4C43DEF9110641F300E55CBF /* ThreadPlanShouldStopHere.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanShouldStopHere.h; path = include/lldb/Target/ThreadPlanShouldStopHere.h; sourceTree = "<group>"; };
 		4C43DEFA110641F300E55CBF /* ThreadPlanShouldStopHere.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanShouldStopHere.cpp; path = source/Target/ThreadPlanShouldStopHere.cpp; sourceTree = "<group>"; };
 		4C43DF8511069BFD00E55CBF /* ThreadPlanStepInRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanStepInRange.h; path = include/lldb/Target/ThreadPlanStepInRange.h; sourceTree = "<group>"; };
@@ -1155,7 +1159,6 @@
 			children = (
 				26C9DF02113C5B80006B0F94 /* Include */,
 				26F5C32810F3DF7D009D5894 /* Libraries */,
-				266960581199F4230075C61A /* Scripts */,
 				08FB7795FE84155DC02AAC07 /* Source */,
 				26F5C22410F3D950009D5894 /* Tools */,
 				1AB674ADFE9D54B511CA2CBB /* Products */,
@@ -1166,6 +1169,7 @@
 		08FB7795FE84155DC02AAC07 /* Source */ = {
 			isa = PBXGroup;
 			children = (
+				266960581199F4230075C61A /* Scripts */,
 				26BC7E7410F1B85900F91463 /* lldb.cpp */,
 				26BC7E7510F1B85900F91463 /* lldb-log.cpp */,
 				26BC7C2A10F1B3BC00F91463 /* lldb-private.h */,
@@ -2064,6 +2068,8 @@
 				260C847510F50EFC00BB2B04 /* ThreadPlanStepThrough.cpp */,
 				4CEDAED311754F5E00E875A6 /* ThreadPlanStepUntil.h */,
 				2660D9FE11922A7F00958FBD /* ThreadPlanStepUntil.cpp */,
+				4C1AB23E1263E61100D0F04A /* ThreadPlanTestCondition.h */,
+				4C1AB23A1263E5F400D0F04A /* ThreadPlanTestCondition.cpp */,
 				4C08CDEB11C81F1E001610A8 /* ThreadSpec.h */,
 				4C08CDE711C81EF8001610A8 /* ThreadSpec.cpp */,
 				4C00986F11500B4300F316B0 /* UnixSignals.h */,
@@ -2384,6 +2390,7 @@
 				4C0A91D912511CB900CA6636 /* AppleObjCTrampolineHandler.h in Headers */,
 				4C0A91DB12511CB900CA6636 /* AppleThreadPlanStepThroughObjCTrampoline.h in Headers */,
 				26424E3F125986D30016D82C /* ValueObjectConstResult.h in Headers */,
+				4C1AB23F1263E61100D0F04A /* ThreadPlanTestCondition.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2438,7 +2445,6 @@
 			isa = PBXProject;
 			buildConfigurationList = 1DEB91EF08733DB70010E9CD /* Build configuration list for PBXProject "lldb" */;
 			compatibilityVersion = "Xcode 3.1";
-			developmentRegion = English;
 			hasScannedForEncodings = 1;
 			knownRegions = (
 				en,
@@ -2856,6 +2862,7 @@
 				4C0A91D812511CB900CA6636 /* AppleObjCTrampolineHandler.cpp in Sources */,
 				4C0A91DA12511CB900CA6636 /* AppleThreadPlanStepThroughObjCTrampoline.cpp in Sources */,
 				26424E3D125986CB0016D82C /* ValueObjectConstResult.cpp in Sources */,
+				4C1AB23B1263E5F400D0F04A /* ThreadPlanTestCondition.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: lldb/trunk/source/Breakpoint/Breakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/Breakpoint.cpp?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/Breakpoint.cpp (original)
+++ lldb/trunk/source/Breakpoint/Breakpoint.cpp Thu Oct 14 18:45:03 2010
@@ -185,6 +185,24 @@
         return m_options.GetThreadSpec()->GetTID();
 }
 
+void 
+Breakpoint::SetCondition (const char *condition)
+{
+    m_options.SetCondition (condition);
+}
+
+ThreadPlan *
+Breakpoint::GetThreadPlanToTestCondition (ExecutionContext &exe_ctx, lldb::BreakpointLocationSP loc_sp, Stream &error)
+{
+    return m_options.GetThreadPlanToTestCondition (exe_ctx, loc_sp, error);
+}
+
+const char *
+Breakpoint::GetConditionText ()
+{
+    return m_options.GetConditionText();
+}
+
 // This function is used when "baton" doesn't need to be freed
 void
 Breakpoint::SetCallback (BreakpointHitCallback callback, void *baton, bool is_synchronous)

Modified: lldb/trunk/source/Breakpoint/BreakpointLocation.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointLocation.cpp?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointLocation.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointLocation.cpp Thu Oct 14 18:45:03 2010
@@ -18,6 +18,7 @@
 #include "lldb/Breakpoint/StoppointCallbackContext.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadPlan.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Core/StreamString.h"
 #include "lldb/lldb-private-log.h"
@@ -131,12 +132,35 @@
     GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous);
 }
 
+
 void
 BreakpointLocation::ClearCallback ()
 {
     GetLocationOptions()->ClearCallback();
 }
 
+void 
+BreakpointLocation::SetCondition (const char *condition)
+{
+    GetLocationOptions()->SetCondition (condition);
+}
+
+ThreadPlan *
+BreakpointLocation::GetThreadPlanToTestCondition (ExecutionContext &exe_ctx, Stream &error)
+{
+    lldb::BreakpointLocationSP my_sp(m_owner.GetLocationSP(this));
+    if (m_options_ap.get())
+        return m_options_ap->GetThreadPlanToTestCondition (exe_ctx, my_sp, error);
+    else
+        return m_owner.GetThreadPlanToTestCondition (exe_ctx, my_sp, error);
+}
+
+const char *
+BreakpointLocation::GetConditionText ()
+{
+    return GetLocationOptions()->GetConditionText();
+}
+
 uint32_t
 BreakpointLocation::GetIgnoreCount ()
 {
@@ -185,6 +209,7 @@
 BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
 {
     bool should_stop = true;
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
 
     m_hit_count++;
 
@@ -194,13 +219,31 @@
     if (m_hit_count <= GetIgnoreCount())
         return false;
 
-    // Tell if the callback is synchronous here.
+    // Next in order of importance is the condition.  See if it is true:
+    StreamString errors;
+
+    // We only run synchronous callbacks in ShouldStop:
     context->is_synchronous = true;
     should_stop = InvokeCallback (context);
-        
+    
+    // The SYNCHRONOUS callback says we should stop, next try the condition.
+    
+    if (should_stop)
+    {
+        ThreadPlanSP condition_plan_sp(GetThreadPlanToTestCondition(context->exe_ctx, errors));
+        if (log && errors.GetSize() > 0)
+        {
+            log->Printf("Error evaluating condition: \"%s\".\n", errors.GetData());
+        }
+        else if (condition_plan_sp != NULL)
+        {
+            context->exe_ctx.thread->QueueThreadPlan(condition_plan_sp, false);
+            return false;
+        }
+    }
+    
     if (should_stop)
     {
-        Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
         if (log)
         {
             StreamString s;
@@ -217,6 +260,12 @@
     return m_bp_site_sp.get() != NULL;
 }
 
+lldb::BreakpointSiteSP
+BreakpointLocation::GetBreakpointSite() const
+{
+    return m_bp_site_sp;
+}
+
 bool
 BreakpointLocation::ResolveBreakpointSite ()
 {

Modified: lldb/trunk/source/Breakpoint/BreakpointOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointOptions.cpp?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/BreakpointOptions.cpp (original)
+++ lldb/trunk/source/Breakpoint/BreakpointOptions.cpp Thu Oct 14 18:45:03 2010
@@ -15,8 +15,11 @@
 // Project includes
 #include "lldb/Core/Stream.h"
 #include "lldb/Core/StringList.h"
+#include "lldb/Core/Value.h"
 #include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Target/Process.h"
 #include "lldb/Target/ThreadSpec.h"
+#include "lldb/Target/ThreadPlanTestCondition.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -36,7 +39,8 @@
     m_callback_is_synchronous (false),
     m_enabled (true),
     m_ignore_count (0),
-    m_thread_spec_ap (NULL)
+    m_thread_spec_ap (NULL),
+    m_condition_ap()
 {
 }
 
@@ -49,10 +53,13 @@
     m_callback_is_synchronous (rhs.m_callback_is_synchronous),
     m_enabled (rhs.m_enabled),
     m_ignore_count (rhs.m_ignore_count),
-    m_thread_spec_ap (NULL)
+    m_thread_spec_ap (NULL),
+    m_condition_ap (NULL)
 {
     if (rhs.m_thread_spec_ap.get() != NULL)
         m_thread_spec_ap.reset (new ThreadSpec(*rhs.m_thread_spec_ap.get()));
+    if (rhs.m_condition_ap.get())
+        m_condition_ap.reset (new ClangUserExpression (rhs.m_condition_ap->GetUserText()));
 }
 
 //----------------------------------------------------------------------
@@ -68,6 +75,8 @@
     m_ignore_count = rhs.m_ignore_count;
     if (rhs.m_thread_spec_ap.get() != NULL)
         m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
+    if (rhs.m_condition_ap.get())
+        m_condition_ap.reset (new ClangUserExpression (rhs.m_condition_ap->GetUserText()));
     return *this;
 }
 
@@ -107,7 +116,8 @@
 void
 BreakpointOptions::ClearCallback ()
 {
-    m_callback = NULL;
+    m_callback = BreakpointOptions::NullCallback;
+    m_callback_is_synchronous = false;
     m_callback_baton_sp.reset();
 }
 
@@ -145,6 +155,71 @@
     return m_callback != BreakpointOptions::NullCallback;
 }
 
+void 
+BreakpointOptions::SetCondition (const char *condition)
+{
+    if (condition == NULL || condition[0] == '\0')
+    {
+        if (m_condition_ap.get())
+            m_condition_ap.reset();
+    }
+    else
+    {
+        m_condition_ap.reset(new ClangUserExpression (condition));
+    }
+}
+
+ThreadPlan * 
+BreakpointOptions::GetThreadPlanToTestCondition (ExecutionContext &exe_ctx, 
+                                                 lldb::BreakpointLocationSP break_loc_sp,
+                                                 Stream &error_stream)
+{
+    // No condition means we should stop, so return NULL.
+    if (!m_condition_ap.get())
+        return NULL;
+        
+    // FIXME: I shouldn't have to do this, the process should handle it for me:
+    if (!exe_ctx.process->GetDynamicCheckers())
+    {
+        DynamicCheckerFunctions *dynamic_checkers = new DynamicCheckerFunctions();
+        
+        StreamString install_errors;
+        
+        if (!dynamic_checkers->Install(install_errors, exe_ctx))
+        {
+            error_stream.Printf("Couldn't install dynamic checkers into the execution context: %s\n", install_errors.GetData());
+            return NULL;
+        }
+        
+        exe_ctx.process->SetDynamicCheckers(dynamic_checkers);
+    }
+
+    if (!m_condition_ap->Parse (error_stream, exe_ctx))
+    {
+        // Errors mean we should stop.
+        return NULL;
+    }
+    // FIXME: When we can execute static expressions without running the target, we should check that here,
+    // and return something to indicate we should stop or just continue.
+
+    ThreadPlan *new_plan = new ThreadPlanTestCondition (*exe_ctx.thread, 
+                                                        exe_ctx, 
+                                                        m_condition_ap.get(), 
+                                                        break_loc_sp, 
+                                                        true);
+    
+    return new_plan;
+}
+
+const char *
+BreakpointOptions::GetConditionText ()
+{
+    if (m_condition_ap.get())
+        return m_condition_ap->GetUserText();
+    else
+        return "<No Condition>";
+}
+
 //------------------------------------------------------------------
 // Enabled/Ignore Count
 //------------------------------------------------------------------
@@ -234,6 +309,14 @@
         if (level != eDescriptionLevelBrief)
             s->EOL();
         m_callback_baton_sp->GetDescription (s, level);
+    }
+    if (m_condition_ap.get())
+    {
+       if (level != eDescriptionLevelBrief)
+       {
+            s->EOL();
+            s->Printf("Condition: %s\n", m_condition_ap->GetUserText());
+        }
     }    
 }
 

Modified: lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp Thu Oct 14 18:45:03 2010
@@ -547,9 +547,25 @@
     //                                  2). the full breakpoint & location canonical representation
     //                                  3). the word "to" or a hyphen, representing a range (in which case there
     //                                      had *better* be an entry both before & after of one of the first two types.
+    // If args is empty, we will use the last created breakpoint (if there is one.)
 
     Args temp_args;
 
+    if (args.GetArgumentCount() == 0)
+    {
+        if (target->GetLastCreatedBreakpoint() != NULL)
+        {
+            valid_ids->AddBreakpointID (BreakpointID(target->GetLastCreatedBreakpoint()->GetID(), LLDB_INVALID_BREAK_ID));
+            result.SetStatus (eReturnStatusSuccessFinishNoResult);
+        } 
+        else
+        {   
+            result.AppendError("No breakpoint specified and no last created breakpoint.");
+            result.SetStatus (eReturnStatusFailed);
+        }
+        return;
+    }
+    
     // Create a new Args variable to use; copy any non-breakpoint-id-ranges stuff directly from the old ARGS to
     // the new TEMP_ARGS.  Do not copy breakpoint id range strings over; instead generate a list of strings for
     // all the breakpoint ids in the range, and shove all of those breakpoint id strings into TEMP_ARGS.
@@ -1076,16 +1092,15 @@
 
     if (args.GetArgumentCount() == 0)
     {
-        // No breakpoint selected; disable all currently set breakpoints.
-        if (args.GetArgumentCount() != 0)
+        if (!m_interpreter.Confirm ("About to delete all breakpoints, do you want to do that?", true))
         {
-            result.AppendErrorWithFormat ("Specify breakpoints to delete with the -i option.\n");
-            result.SetStatus (eReturnStatusFailed);
-            return false;
+            result.AppendMessage("Operation cancelled...");
+        }
+        else
+        {
+            target->RemoveAllBreakpoints ();
+            result.AppendMessageWithFormat ("All breakpoints removed. (%d breakpoints)\n", num_breakpoints);
         }
-
-        target->RemoveAllBreakpoints ();
-        result.AppendMessageWithFormat ("All breakpoints removed. (%d breakpoints)\n", num_breakpoints);
         result.SetStatus (eReturnStatusSuccessFinishNoResult);
     }
     else
@@ -1143,10 +1158,12 @@
     m_thread_index (UINT32_MAX),
     m_thread_name(),
     m_queue_name(),
+    m_condition (),
     m_enable_passed (false),
     m_enable_value (false),
     m_name_passed (false),
-    m_queue_passed (false)
+    m_queue_passed (false),
+    m_condition_passed (false)
 {
 }
 
@@ -1162,9 +1179,10 @@
 { LLDB_OPT_SET_ALL, false, "thread-id",    't', required_argument, NULL, NULL, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument."},
 { LLDB_OPT_SET_ALL, false, "thread-name",  'T', required_argument, NULL, NULL, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument."},
 { LLDB_OPT_SET_ALL, false, "queue-name",   'q', required_argument, NULL, NULL, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument."},
+{ LLDB_OPT_SET_ALL, false, "condition",    'c', required_argument, NULL, NULL, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true."},
 { LLDB_OPT_SET_1,   false, "enable",       'e', no_argument,       NULL, NULL, eArgTypeNone, "Enable the breakpoint."},
 { LLDB_OPT_SET_2,   false, "disable",      'd', no_argument,       NULL, NULL, eArgTypeNone, "Disable the breakpoint."},
-{ 0,                false, NULL,            0 , 0,                 NULL, 0, eArgTypeNone, NULL }
+{ 0,                false, NULL,            0 , 0,                 NULL, 0,    eArgTypeNone, NULL }
 };
 
 const lldb::OptionDefinition*
@@ -1181,6 +1199,13 @@
 
     switch (short_option)
     {
+        case 'c':
+            if (option_arg != NULL)
+                m_condition = option_arg;
+            else
+                m_condition.clear();
+            m_condition_passed = true;
+            break;
         case 'd':
             m_enable_passed = true;
             m_enable_value = false;
@@ -1243,9 +1268,11 @@
     m_thread_index = UINT32_MAX;
     m_thread_name.clear();
     m_queue_name.clear();
+    m_condition.clear();
     m_enable_passed = false;
     m_queue_passed = false;
     m_name_passed = false;
+    m_condition_passed = false;
 }
 
 //-------------------------------------------------------------------------
@@ -1297,13 +1324,6 @@
     CommandReturnObject &result
 )
 {
-    if (command.GetArgumentCount() == 0)
-    {
-        result.AppendError ("No breakpoints specified.");
-        result.SetStatus (eReturnStatusFailed);
-        return false;
-    }
-
     Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
     if (target == NULL)
     {
@@ -1351,6 +1371,9 @@
                             
                         if (m_options.m_enable_passed)
                             location->SetEnabled (m_options.m_enable_value);
+                            
+                        if (m_options.m_condition_passed)
+                            location->SetCondition (m_options.m_condition.c_str());
                     }
                 }
                 else
@@ -1372,7 +1395,9 @@
                         
                     if (m_options.m_enable_passed)
                         bp->SetEnabled (m_options.m_enable_value);
-
+                        
+                    if (m_options.m_condition_passed)
+                        bp->SetCondition (m_options.m_condition.c_str());
                 }
             }
         }

Modified: lldb/trunk/source/Commands/CommandObjectBreakpoint.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpoint.h?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectBreakpoint.h (original)
+++ lldb/trunk/source/Commands/CommandObjectBreakpoint.h Thu Oct 14 18:45:03 2010
@@ -167,10 +167,12 @@
         uint32_t m_thread_index;
         std::string m_thread_name;
         std::string m_queue_name;
+        std::string m_condition;
         bool m_enable_passed;
         bool m_enable_value;
         bool m_name_passed;
         bool m_queue_passed;
+        bool m_condition_passed;
 
     };
 

Modified: lldb/trunk/source/Core/Event.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Event.cpp?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/source/Core/Event.cpp (original)
+++ lldb/trunk/source/Core/Event.cpp Thu Oct 14 18:45:03 2010
@@ -49,12 +49,6 @@
 }
 
 void
-Event::Clear()
-{
-    m_data_ap.reset();
-}
-
-void
 Event::Dump (Stream *s) const
 {
     s->Printf("%p Event: broadcaster = %p, type = 0x%8.8x, data = ", this, m_broadcaster, m_type);
@@ -69,37 +63,6 @@
     }
 }
 
-Broadcaster *
-Event::GetBroadcaster () const
-{
-    return m_broadcaster;
-}
-
-bool
-Event::BroadcasterIs (Broadcaster *broadcaster)
-{
-    return broadcaster == m_broadcaster;
-}
-
-uint32_t
-Event::GetType() const
-{
-    return m_type;
-}
-
-
-EventData *
-Event::GetData ()
-{
-    return m_data_ap.get();
-}
-
-const EventData *
-Event::GetData () const
-{
-    return m_data_ap.get();
-}
-
 void
 Event::DoOnRemoval ()
 {
@@ -107,12 +70,6 @@
         m_data_ap->DoOnRemoval (this);
 }
 
-void
-Event::SetBroadcaster (Broadcaster *broadcaster)
-{
-    m_broadcaster = broadcaster;
-}
-
 EventData::EventData()
 {
 }

Modified: lldb/trunk/source/Expression/ClangExpressionParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionParser.cpp?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionParser.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionParser.cpp Thu Oct 14 18:45:03 2010
@@ -447,7 +447,7 @@
             return err;
         }
         
-        if (m_expr.NeedsValidation())
+        if (m_expr.NeedsValidation() && exe_ctx.process->GetDynamicCheckers())
         {
             /* 
              Disabled temporarily - TODO Centralize and re-enable this inside Process to avoid race conditions

Modified: lldb/trunk/source/Expression/ClangFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangFunction.cpp?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangFunction.cpp (original)
+++ lldb/trunk/source/Expression/ClangFunction.cpp Thu Oct 14 18:45:03 2010
@@ -539,9 +539,11 @@
             // Not really sure what to do if Halt fails here...
             if (log)
                 if (try_all_threads)
-                    log->Printf ("Running function with timeout: %d timed out, trying with all threads enabled.", single_thread_timeout_usec);
+                    log->Printf ("Running function with timeout: %d timed out, trying with all threads enabled.",
+                                 single_thread_timeout_usec);
                 else
-                    log->Printf ("Running function with timeout: %d timed out, abandoning execution.", single_thread_timeout_usec);
+                    log->Printf ("Running function with timeout: %d timed out, abandoning execution.", 
+                                 single_thread_timeout_usec);
             
             if (exe_ctx.process->Halt().Success())
             {

Modified: lldb/trunk/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangUserExpression.cpp?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/trunk/source/Expression/ClangUserExpression.cpp Thu Oct 14 18:45:03 2010
@@ -215,27 +215,18 @@
 }
 
 bool
-ClangUserExpression::Execute (Stream &error_stream,
-                              ExecutionContext &exe_ctx,
-                              ClangExpressionVariable *&result)
+ClangUserExpression::PrepareToExecuteJITExpression (Stream &error_stream,
+                                       ExecutionContext &exe_ctx,
+                                       lldb::addr_t &struct_address,
+                                       lldb::addr_t object_ptr)
 {
     Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
 
-    if (m_dwarf_opcodes.get())
+    if (m_jit_addr != LLDB_INVALID_ADDRESS)
     {
-        // TODO execute the JITted opcodes
-        
-        error_stream.Printf("We don't currently support executing DWARF expressions");
-        
-        return false;
-    }
-    else if (m_jit_addr != LLDB_INVALID_ADDRESS)
-    {
-        lldb::addr_t struct_address;
         
         Error materialize_error;
         
-        lldb::addr_t object_ptr = NULL;
         
         if (m_needs_object_ptr && !(m_expr_decl_map->GetObjectPointer(object_ptr, &exe_ctx, materialize_error)))
         {
@@ -274,6 +265,64 @@
                 }
             }
         }
+    }
+    return true;
+}
+
+ThreadPlan *
+ClangUserExpression::GetThreadPlanToExecuteJITExpression (Stream &error_stream,
+                                       ExecutionContext &exe_ctx)
+{
+    lldb::addr_t struct_address;
+            
+    lldb::addr_t object_ptr = NULL;
+    
+    PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr);
+    
+    return ClangFunction::GetThreadPlanToCallFunction (exe_ctx, 
+                                        m_jit_addr, 
+                                        struct_address, 
+                                        error_stream,
+                                        true,
+                                        true, 
+                                        (m_needs_object_ptr ? &object_ptr : NULL));
+}
+
+bool
+ClangUserExpression::FinalizeJITExecution (Stream &error_stream,
+                                           ExecutionContext &exe_ctx,
+                                           ClangExpressionVariable *&result)
+{
+    Error expr_error;
+    
+    if (!m_expr_decl_map->Dematerialize(&exe_ctx, result, expr_error))
+    {
+        error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error"));
+        return false;
+    }
+    return true;
+}        
+
+bool
+ClangUserExpression::Execute (Stream &error_stream,
+                              ExecutionContext &exe_ctx,
+                              ClangExpressionVariable *&result)
+{
+    if (m_dwarf_opcodes.get())
+    {
+        // TODO execute the JITted opcodes
+        
+        error_stream.Printf("We don't currently support executing DWARF expressions");
+        
+        return false;
+    }
+    else if (m_jit_addr != LLDB_INVALID_ADDRESS)
+    {
+        lldb::addr_t struct_address;
+                
+        lldb::addr_t object_ptr = NULL;
+        
+        PrepareToExecuteJITExpression (error_stream, exe_ctx, struct_address, object_ptr);
         
         ClangFunction::ExecutionResults execution_result = 
         ClangFunction::ExecuteFunction (exe_ctx, 
@@ -312,15 +361,7 @@
             return false;
         }
         
-        Error expr_error;
-        
-        if (!m_expr_decl_map->Dematerialize(&exe_ctx, result, expr_error))
-        {
-            error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error"));
-            return false;
-        }
-        
-        return true;
+        return FinalizeJITExecution (error_stream, exe_ctx, result);
     }
     else
     {

Modified: lldb/trunk/source/Target/Process.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/source/Target/Process.cpp (original)
+++ lldb/trunk/source/Target/Process.cpp Thu Oct 14 18:45:03 2010
@@ -82,9 +82,9 @@
     m_exit_string (),
     m_thread_list (this),
     m_notifications (),
+    m_persistent_vars(),
     m_listener(listener),
-    m_unix_signals (),
-    m_persistent_vars()
+    m_unix_signals ()
 {
     UpdateInstanceName();
 

Modified: lldb/trunk/source/Target/StopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StopInfo.cpp?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/source/Target/StopInfo.cpp (original)
+++ lldb/trunk/source/Target/StopInfo.cpp Thu Oct 14 18:45:03 2010
@@ -56,6 +56,14 @@
     {
     }
     
+    StopInfoBreakpoint (Thread &thread, break_id_t break_id, bool should_stop) :
+        StopInfo (thread, break_id),
+        m_description(),
+        m_should_stop (should_stop),
+        m_should_stop_is_valid (true)
+    {
+    }
+
     virtual ~StopInfoBreakpoint ()
     {
     }
@@ -367,6 +375,12 @@
 }
 
 StopInfoSP
+StopInfo::CreateStopReasonWithBreakpointSiteID (Thread &thread, break_id_t break_id, bool should_stop)
+{
+    return StopInfoSP (new StopInfoBreakpoint (thread, break_id, should_stop));
+}
+
+StopInfoSP
 StopInfo::CreateStopReasonWithWatchpointID (Thread &thread, break_id_t watch_id)
 {
     return StopInfoSP (new StopInfoWatchpoint (thread, watch_id));

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=116542&r1=116541&r2=116542&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Thu Oct 14 18:45:03 2010
@@ -252,6 +252,12 @@
 
         bp_sp->ResolveBreakpoint();
     }
+    
+    if (!internal && bp_sp)
+    {
+        m_last_created_breakpoint = bp_sp;
+    }
+    
     return bp_sp;
 }
 
@@ -265,6 +271,8 @@
     m_breakpoint_list.RemoveAll (true);
     if (internal_also)
         m_internal_breakpoint_list.RemoveAll (false);
+        
+    m_last_created_breakpoint.reset();
 }
 
 void
@@ -303,7 +311,11 @@
         if (LLDB_BREAK_ID_IS_INTERNAL (break_id))
             m_internal_breakpoint_list.Remove(break_id, false);
         else
+        {
+            if (m_last_created_breakpoint->GetID() == break_id)
+                m_last_created_breakpoint.reset();
             m_breakpoint_list.Remove(break_id, true);
+        }
         return true;
     }
     return false;

Added: lldb/trunk/source/Target/ThreadPlanTestCondition.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadPlanTestCondition.cpp?rev=116542&view=auto
==============================================================================
--- lldb/trunk/source/Target/ThreadPlanTestCondition.cpp (added)
+++ lldb/trunk/source/Target/ThreadPlanTestCondition.cpp Thu Oct 14 18:45:03 2010
@@ -0,0 +1,182 @@
+//===-- ThreadPlanTestCondition.cpp ---------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/ThreadPlanTestCondition.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+
+#include "lldb/lldb-private-log.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/Stream.h"
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObject.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/Symbol.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/StopInfo.h"
+#include "lldb/Target/Thread.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+//----------------------------------------------------------------------
+// ThreadPlanTestCondition: Step through a stack range, either stepping over or into
+// based on the value of \a type.
+//----------------------------------------------------------------------
+
+ThreadPlanTestCondition::ThreadPlanTestCondition (
+        Thread& thread,
+        ExecutionContext &exe_ctx, 
+        ClangUserExpression *expression, 
+        lldb::BreakpointLocationSP break_loc_sp, 
+        bool stop_others) :
+    ThreadPlan (ThreadPlan::eKindTestCondition, "test condition", thread, eVoteNoOpinion, eVoteNoOpinion),
+    m_exe_ctx (exe_ctx),
+    m_expression (expression),
+    m_break_loc_sp (break_loc_sp),
+    m_did_stop (false),
+    m_stop_others (stop_others)
+{
+}
+
+ThreadPlanTestCondition::~ThreadPlanTestCondition ()
+{
+}
+
+bool
+ThreadPlanTestCondition::ValidatePlan (Stream *error)
+{
+    return true;
+}
+
+void 
+ThreadPlanTestCondition::GetDescription (Stream *s, lldb::DescriptionLevel level)
+{
+
+}
+
+bool 
+ThreadPlanTestCondition::ShouldStop (Event *event_ptr)
+{    
+    Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
+    if (m_thread.IsThreadPlanDone(m_expression_plan_sp.get()))
+    {
+        ClangExpressionVariable *expr_result = NULL;
+        StreamString error_stream;
+        m_expression->FinalizeJITExecution(error_stream, m_exe_ctx, expr_result);
+        
+        ValueObjectSP result_sp (expr_result->GetExpressionResult(&m_exe_ctx));
+        if (result_sp)
+        {
+            // FIXME: This is not the right answer, we should have a "GetValueAsBoolean..."
+            Scalar scalar_value = result_sp->GetValue().ResolveValue (&m_exe_ctx, result_sp->GetClangAST());
+            if (scalar_value.IsValid())
+            {
+                if (scalar_value.ULongLong(1) == 0)
+                    m_did_stop = false;
+                else
+                    m_did_stop = true;
+            }
+            if (log)
+                log->Printf("Condition successfully evaluated, result is %s.\n", m_did_stop ? "true" : "false");
+        }
+        else
+        {
+            if (log)
+                log->Printf("Failed to get a result from the expression, error: \"%s\"\n", error_stream.GetData());
+            m_did_stop = true;
+        }
+    }
+    else if (m_exe_ctx.thread->WasThreadPlanDiscarded (m_expression_plan_sp.get()))
+    {
+        if (log)
+            log->Printf("ExecuteExpression thread plan was discarded.\n");
+        m_did_stop = true; 
+    }
+    
+    // Now we have to change the event to a breakpoint event and mark it up appropriately:
+    Process::ProcessEventData *new_data = new Process::ProcessEventData (m_thread.GetProcess().GetSP(), eStateStopped);
+    event_ptr->SetData(new_data);
+    event_ptr->SetType(Process::eBroadcastBitStateChanged);
+    m_thread.SetStopInfo(StopInfo::CreateStopReasonWithBreakpointSiteID (m_thread, 
+                                                                         m_break_loc_sp->GetBreakpointSite()->GetID(),
+                                                                         m_did_stop));
+    if (m_did_stop)
+    {
+        Process::ProcessEventData::SetRestartedInEvent (event_ptr, false);
+    }
+    else
+    {
+        Process::ProcessEventData::SetRestartedInEvent (event_ptr, true);
+    }
+    
+    SetPlanComplete();
+    return m_did_stop;
+}
+
+bool
+ThreadPlanTestCondition::PlanExplainsStop ()
+{
+    // We explain all stops, and we just can the execution and return true if we stop for any
+    // reason other than that our expression execution is done.
+    return true;
+}
+
+Vote
+ThreadPlanTestCondition::ShouldReportStop (Event *event_ptr)
+{
+    if (m_did_stop)
+    {
+        return eVoteYes;
+    }
+    else 
+    {
+        return eVoteNo;
+    }
+}
+
+void
+ThreadPlanTestCondition::DidPush()
+{
+    StreamString error_stream;
+    m_expression_plan_sp.reset(m_expression->GetThreadPlanToExecuteJITExpression (error_stream, m_exe_ctx));
+    m_thread.QueueThreadPlan (m_expression_plan_sp, false);
+}
+
+bool
+ThreadPlanTestCondition::StopOthers ()
+{
+    return m_stop_others;
+}
+
+bool
+ThreadPlanTestCondition::WillStop ()
+{
+    return true;
+}
+
+StateType
+ThreadPlanTestCondition::RunState ()
+{
+    return eStateRunning;
+}
+
+bool
+ThreadPlanTestCondition::MischiefManaged ()
+{
+    // If we get a stop we're done, we don't puase in the middle of 
+    // condition execution.
+    return true;
+}





More information about the lldb-commits mailing list