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.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@116542 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Breakpoint/BreakpointLocation.cpp b/source/Breakpoint/BreakpointLocation.cpp
index dc45654..609a41e 100644
--- a/source/Breakpoint/BreakpointLocation.cpp
+++ b/source/Breakpoint/BreakpointLocation.cpp
@@ -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)
{
- Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
+ 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)
+ {
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 ()
{