diff options
Diffstat (limited to 'lldb/source/Breakpoint/BreakpointLocation.cpp')
| -rw-r--r-- | lldb/source/Breakpoint/BreakpointLocation.cpp | 104 |
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 |

