summaryrefslogtreecommitdiffstats
path: root/lldb/source/Breakpoint/BreakpointLocation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Breakpoint/BreakpointLocation.cpp')
-rw-r--r--lldb/source/Breakpoint/BreakpointLocation.cpp104
1 files changed, 102 insertions, 2 deletions
diff --git a/lldb/source/Breakpoint/BreakpointLocation.cpp b/lldb/source/Breakpoint/BreakpointLocation.cpp
index 71e8eb7c868..04142b268e4 100644
--- a/lldb/source/Breakpoint/BreakpointLocation.cpp
+++ b/lldb/source/Breakpoint/BreakpointLocation.cpp
@@ -240,9 +240,109 @@ BreakpointLocation::SetCondition (const char *condition)
}
const char *
-BreakpointLocation::GetConditionText () const
+BreakpointLocation::GetConditionText (size_t *hash) const
{
- return GetOptionsNoCreate()->GetConditionText();
+ return GetOptionsNoCreate()->GetConditionText(hash);
+}
+
+bool
+BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
+{
+ Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
+
+ size_t condition_hash;
+ const char *condition_text = GetConditionText(&condition_hash);
+
+ if (!condition_text)
+ return false;
+
+ if (condition_hash != m_condition_hash ||
+ !m_user_expression_sp ||
+ !m_user_expression_sp->MatchesContext(exe_ctx))
+ {
+ m_user_expression_sp.reset(new ClangUserExpression(condition_text,
+ NULL,
+ lldb::eLanguageTypeUnknown,
+ ClangUserExpression::eResultTypeAny));
+
+ StreamString errors;
+
+ if (!m_user_expression_sp->Parse(errors,
+ exe_ctx,
+ eExecutionPolicyOnlyWhenNeeded,
+ true))
+ {
+ error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s",
+ errors.GetData());
+ m_user_expression_sp.reset();
+ return false;
+ }
+
+ m_condition_hash = condition_hash;
+ }
+
+ // We need to make sure the user sees any parse errors in their condition, so we'll hook the
+ // constructor errors up to the debugger's Async I/O.
+
+ ValueObjectSP result_value_sp;
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = true;
+ const bool try_all_threads = true;
+
+ Error expr_error;
+
+ StreamString execution_errors;
+
+ ClangExpressionVariableSP result_variable_sp;
+
+ ExecutionResults result_code =
+ m_user_expression_sp->Execute(execution_errors,
+ exe_ctx,
+ unwind_on_error,
+ ignore_breakpoints,
+ m_user_expression_sp,
+ result_variable_sp,
+ try_all_threads,
+ ClangUserExpression::kDefaultTimeout);
+
+ bool ret;
+
+ if (result_code == eExecutionCompleted)
+ {
+ result_value_sp = result_variable_sp->GetValueObject();
+
+ if (result_value_sp)
+ {
+ Scalar scalar_value;
+ if (result_value_sp->ResolveValue (scalar_value))
+ {
+ if (scalar_value.ULongLong(1) == 0)
+ ret = false;
+ else
+ ret = true;
+ if (log)
+ log->Printf("Condition successfully evaluated, result is %s.\n",
+ ret ? "true" : "false");
+ }
+ else
+ {
+ ret = false;
+ error.SetErrorString("Failed to get an integer result from the expression");
+ }
+ }
+ else
+ {
+ ret = false;
+ error.SetErrorString("Failed to get any result from the expression");
+ }
+ }
+ else
+ {
+ ret = false;
+ error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData());
+ }
+
+ return ret;
}
uint32_t
OpenPOWER on IntegriCloud