180814287SRaphael Isemann //===-- BreakpointLocation.cpp --------------------------------------------===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner
930fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointLocation.h"
1030fdc8d8SChris Lattner #include "lldb/Breakpoint/BreakpointID.h"
1130fdc8d8SChris Lattner #include "lldb/Breakpoint/StoppointCallbackContext.h"
125b52f0c7SJim Ingham #include "lldb/Core/Debugger.h"
131f746071SGreg Clayton #include "lldb/Core/Module.h"
14a78bd7ffSZachary Turner #include "lldb/Core/ValueObject.h"
15579e70c9SSean Callanan #include "lldb/Expression/DiagnosticManager.h"
16937e3964SBruce Mitchener #include "lldb/Expression/ExpressionVariable.h"
17151c032cSJim Ingham #include "lldb/Expression/UserExpression.h"
181f746071SGreg Clayton #include "lldb/Symbol/CompileUnit.h"
191f746071SGreg Clayton #include "lldb/Symbol/Symbol.h"
20151c032cSJim Ingham #include "lldb/Symbol/TypeSystem.h"
211f746071SGreg Clayton #include "lldb/Target/Process.h"
22b9c1b51eSKate Stone #include "lldb/Target/Target.h"
2330fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
241b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h"
25c34698a8SPavel Labath #include "lldb/Utility/LLDBLog.h"
266f9e6901SZachary Turner #include "lldb/Utility/Log.h"
27bf9a7730SZachary Turner #include "lldb/Utility/StreamString.h"
2830fdc8d8SChris Lattner
2930fdc8d8SChris Lattner using namespace lldb;
3030fdc8d8SChris Lattner using namespace lldb_private;
3130fdc8d8SChris Lattner
BreakpointLocation(break_id_t loc_id,Breakpoint & owner,const Address & addr,lldb::tid_t tid,bool hardware,bool check_for_resolver)32b9c1b51eSKate Stone BreakpointLocation::BreakpointLocation(break_id_t loc_id, Breakpoint &owner,
33b9c1b51eSKate Stone const Address &addr, lldb::tid_t tid,
34bb19a13cSSaleem Abdulrasool bool hardware, bool check_for_resolver)
35da0bba5cSTatyana Krasnukha : m_being_created(true), m_should_resolve_indirect_functions(false),
36b9c1b51eSKate Stone m_is_reexported(false), m_is_indirect(false), m_address(addr),
37*ee4b6cf5SKazu Hirata m_owner(owner), m_condition_hash(0), m_loc_id(loc_id), m_hit_counter() {
38b9c1b51eSKate Stone if (check_for_resolver) {
391460e4bfSJim Ingham Symbol *symbol = m_address.CalculateSymbolContextSymbol();
40b9c1b51eSKate Stone if (symbol && symbol->IsIndirect()) {
411460e4bfSJim Ingham SetShouldResolveIndirectFunctions(true);
421460e4bfSJim Ingham }
431460e4bfSJim Ingham }
441460e4bfSJim Ingham
451b54c88cSJim Ingham SetThreadID(tid);
46e6bc6cb9SJim Ingham m_being_created = false;
4730fdc8d8SChris Lattner }
4830fdc8d8SChris Lattner
~BreakpointLocation()49b9c1b51eSKate Stone BreakpointLocation::~BreakpointLocation() { ClearBreakpointSite(); }
5030fdc8d8SChris Lattner
GetLoadAddress() const51b9c1b51eSKate Stone lldb::addr_t BreakpointLocation::GetLoadAddress() const {
52f3ef3d2aSGreg Clayton return m_address.GetOpcodeLoadAddress(&m_owner.GetTarget());
5330fdc8d8SChris Lattner }
5430fdc8d8SChris Lattner
GetOptionsSpecifyingKind(BreakpointOptions::OptionKind kind) const55cfb96d84SJim Ingham const BreakpointOptions &BreakpointLocation::GetOptionsSpecifyingKind(
56cfb96d84SJim Ingham BreakpointOptions::OptionKind kind) const {
57d5b44036SJonas Devlieghere if (m_options_up && m_options_up->IsOptionSet(kind))
58cfb96d84SJim Ingham return *m_options_up;
59af26b22cSJim Ingham else
60af26b22cSJim Ingham return m_owner.GetOptions();
61af26b22cSJim Ingham }
62af26b22cSJim Ingham
GetAddress()63b9c1b51eSKate Stone Address &BreakpointLocation::GetAddress() { return m_address; }
6430fdc8d8SChris Lattner
GetBreakpoint()65b9c1b51eSKate Stone Breakpoint &BreakpointLocation::GetBreakpoint() { return m_owner; }
6630fdc8d8SChris Lattner
GetTarget()67b9c1b51eSKate Stone Target &BreakpointLocation::GetTarget() { return m_owner.GetTarget(); }
68151c032cSJim Ingham
IsEnabled() const69b9c1b51eSKate Stone bool BreakpointLocation::IsEnabled() const {
7050df1f96SJohnny Chen if (!m_owner.IsEnabled())
7150df1f96SJohnny Chen return false;
72d5b44036SJonas Devlieghere else if (m_options_up != nullptr)
73d5b44036SJonas Devlieghere return m_options_up->IsEnabled();
7430fdc8d8SChris Lattner else
7550df1f96SJohnny Chen return true;
7630fdc8d8SChris Lattner }
7730fdc8d8SChris Lattner
SetEnabled(bool enabled)78b9c1b51eSKate Stone void BreakpointLocation::SetEnabled(bool enabled) {
79cfb96d84SJim Ingham GetLocationOptions().SetEnabled(enabled);
80b9c1b51eSKate Stone if (enabled) {
8130fdc8d8SChris Lattner ResolveBreakpointSite();
82b9c1b51eSKate Stone } else {
8330fdc8d8SChris Lattner ClearBreakpointSite();
8430fdc8d8SChris Lattner }
85b9c1b51eSKate Stone SendBreakpointLocationChangedEvent(enabled ? eBreakpointEventTypeEnabled
86b9c1b51eSKate Stone : eBreakpointEventTypeDisabled);
8730fdc8d8SChris Lattner }
8830fdc8d8SChris Lattner
IsAutoContinue() const89f08f5c99SJim Ingham bool BreakpointLocation::IsAutoContinue() const {
90d5b44036SJonas Devlieghere if (m_options_up &&
91d5b44036SJonas Devlieghere m_options_up->IsOptionSet(BreakpointOptions::eAutoContinue))
92d5b44036SJonas Devlieghere return m_options_up->IsAutoContinue();
93f08f5c99SJim Ingham else
94f08f5c99SJim Ingham return m_owner.IsAutoContinue();
95f08f5c99SJim Ingham }
96f08f5c99SJim Ingham
SetAutoContinue(bool auto_continue)97f08f5c99SJim Ingham void BreakpointLocation::SetAutoContinue(bool auto_continue) {
98cfb96d84SJim Ingham GetLocationOptions().SetAutoContinue(auto_continue);
99f08f5c99SJim Ingham SendBreakpointLocationChangedEvent(eBreakpointEventTypeAutoContinueChanged);
100f08f5c99SJim Ingham }
101f08f5c99SJim Ingham
SetThreadID(lldb::tid_t thread_id)102b9c1b51eSKate Stone void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) {
1031b54c88cSJim Ingham if (thread_id != LLDB_INVALID_THREAD_ID)
104cfb96d84SJim Ingham GetLocationOptions().SetThreadID(thread_id);
105b9c1b51eSKate Stone else {
10605097246SAdrian Prantl // If we're resetting this to an invalid thread id, then don't make an
10705097246SAdrian Prantl // options pointer just to do that.
108d5b44036SJonas Devlieghere if (m_options_up != nullptr)
109d5b44036SJonas Devlieghere m_options_up->SetThreadID(thread_id);
1101b54c88cSJim Ingham }
111e6bc6cb9SJim Ingham SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
112e6bc6cb9SJim Ingham }
113e6bc6cb9SJim Ingham
GetThreadID()114b9c1b51eSKate Stone lldb::tid_t BreakpointLocation::GetThreadID() {
115af26b22cSJim Ingham const ThreadSpec *thread_spec =
116af26b22cSJim Ingham GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
117cfb96d84SJim Ingham .GetThreadSpecNoCreate();
118af26b22cSJim Ingham if (thread_spec)
119af26b22cSJim Ingham return thread_spec->GetTID();
120e6bc6cb9SJim Ingham else
121e6bc6cb9SJim Ingham return LLDB_INVALID_THREAD_ID;
122e6bc6cb9SJim Ingham }
123e6bc6cb9SJim Ingham
SetThreadIndex(uint32_t index)124b9c1b51eSKate Stone void BreakpointLocation::SetThreadIndex(uint32_t index) {
125e6bc6cb9SJim Ingham if (index != 0)
126cfb96d84SJim Ingham GetLocationOptions().GetThreadSpec()->SetIndex(index);
127b9c1b51eSKate Stone else {
12805097246SAdrian Prantl // If we're resetting this to an invalid thread id, then don't make an
12905097246SAdrian Prantl // options pointer just to do that.
130d5b44036SJonas Devlieghere if (m_options_up != nullptr)
131d5b44036SJonas Devlieghere m_options_up->GetThreadSpec()->SetIndex(index);
132e6bc6cb9SJim Ingham }
133e6bc6cb9SJim Ingham SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
134e6bc6cb9SJim Ingham }
135e6bc6cb9SJim Ingham
GetThreadIndex() const136b9c1b51eSKate Stone uint32_t BreakpointLocation::GetThreadIndex() const {
137af26b22cSJim Ingham const ThreadSpec *thread_spec =
138af26b22cSJim Ingham GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
139cfb96d84SJim Ingham .GetThreadSpecNoCreate();
140af26b22cSJim Ingham if (thread_spec)
141af26b22cSJim Ingham return thread_spec->GetIndex();
142e6bc6cb9SJim Ingham else
143e6bc6cb9SJim Ingham return 0;
144e6bc6cb9SJim Ingham }
145e6bc6cb9SJim Ingham
SetThreadName(const char * thread_name)146b9c1b51eSKate Stone void BreakpointLocation::SetThreadName(const char *thread_name) {
14716fd7511SEugene Zelenko if (thread_name != nullptr)
148cfb96d84SJim Ingham GetLocationOptions().GetThreadSpec()->SetName(thread_name);
149b9c1b51eSKate Stone else {
15005097246SAdrian Prantl // If we're resetting this to an invalid thread id, then don't make an
15105097246SAdrian Prantl // options pointer just to do that.
152d5b44036SJonas Devlieghere if (m_options_up != nullptr)
153d5b44036SJonas Devlieghere m_options_up->GetThreadSpec()->SetName(thread_name);
154e6bc6cb9SJim Ingham }
155e6bc6cb9SJim Ingham SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
156e6bc6cb9SJim Ingham }
157e6bc6cb9SJim Ingham
GetThreadName() const158b9c1b51eSKate Stone const char *BreakpointLocation::GetThreadName() const {
159af26b22cSJim Ingham const ThreadSpec *thread_spec =
160af26b22cSJim Ingham GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
161cfb96d84SJim Ingham .GetThreadSpecNoCreate();
162af26b22cSJim Ingham if (thread_spec)
163af26b22cSJim Ingham return thread_spec->GetName();
164e6bc6cb9SJim Ingham else
16516fd7511SEugene Zelenko return nullptr;
166e6bc6cb9SJim Ingham }
167e6bc6cb9SJim Ingham
SetQueueName(const char * queue_name)168b9c1b51eSKate Stone void BreakpointLocation::SetQueueName(const char *queue_name) {
16916fd7511SEugene Zelenko if (queue_name != nullptr)
170cfb96d84SJim Ingham GetLocationOptions().GetThreadSpec()->SetQueueName(queue_name);
171b9c1b51eSKate Stone else {
17205097246SAdrian Prantl // If we're resetting this to an invalid thread id, then don't make an
17305097246SAdrian Prantl // options pointer just to do that.
174d5b44036SJonas Devlieghere if (m_options_up != nullptr)
175d5b44036SJonas Devlieghere m_options_up->GetThreadSpec()->SetQueueName(queue_name);
176e6bc6cb9SJim Ingham }
177e6bc6cb9SJim Ingham SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
178e6bc6cb9SJim Ingham }
179e6bc6cb9SJim Ingham
GetQueueName() const180b9c1b51eSKate Stone const char *BreakpointLocation::GetQueueName() const {
181af26b22cSJim Ingham const ThreadSpec *thread_spec =
182af26b22cSJim Ingham GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
183cfb96d84SJim Ingham .GetThreadSpecNoCreate();
184af26b22cSJim Ingham if (thread_spec)
185af26b22cSJim Ingham return thread_spec->GetQueueName();
186e6bc6cb9SJim Ingham else
18716fd7511SEugene Zelenko return nullptr;
18830fdc8d8SChris Lattner }
18930fdc8d8SChris Lattner
InvokeCallback(StoppointCallbackContext * context)190b9c1b51eSKate Stone bool BreakpointLocation::InvokeCallback(StoppointCallbackContext *context) {
191d5b44036SJonas Devlieghere if (m_options_up != nullptr && m_options_up->HasCallback())
192d5b44036SJonas Devlieghere return m_options_up->InvokeCallback(context, m_owner.GetID(), GetID());
19330fdc8d8SChris Lattner else
1940136309fSJim Ingham return m_owner.InvokeCallback(context, GetID());
19530fdc8d8SChris Lattner }
19630fdc8d8SChris Lattner
IsCallbackSynchronous()197c8faa8c2SJim Ingham bool BreakpointLocation::IsCallbackSynchronous() {
198c8faa8c2SJim Ingham if (m_options_up != nullptr && m_options_up->HasCallback())
199c8faa8c2SJim Ingham return m_options_up->IsCallbackSynchronous();
200c8faa8c2SJim Ingham else
201cfb96d84SJim Ingham return m_owner.GetOptions().IsCallbackSynchronous();
202c8faa8c2SJim Ingham }
203c8faa8c2SJim Ingham
SetCallback(BreakpointHitCallback callback,void * baton,bool is_synchronous)204b9c1b51eSKate Stone void BreakpointLocation::SetCallback(BreakpointHitCallback callback,
205b9c1b51eSKate Stone void *baton, bool is_synchronous) {
20605097246SAdrian Prantl // The default "Baton" class will keep a copy of "baton" and won't free or
20705097246SAdrian Prantl // delete it when it goes goes out of scope.
208cfb96d84SJim Ingham GetLocationOptions().SetCallback(
2094e4fbe82SZachary Turner callback, std::make_shared<UntypedBaton>(baton), is_synchronous);
210e6bc6cb9SJim Ingham SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);
21130fdc8d8SChris Lattner }
21230fdc8d8SChris Lattner
SetCallback(BreakpointHitCallback callback,const BatonSP & baton_sp,bool is_synchronous)213b9c1b51eSKate Stone void BreakpointLocation::SetCallback(BreakpointHitCallback callback,
214b9c1b51eSKate Stone const BatonSP &baton_sp,
215b9c1b51eSKate Stone bool is_synchronous) {
216cfb96d84SJim Ingham GetLocationOptions().SetCallback(callback, baton_sp, is_synchronous);
217e6bc6cb9SJim Ingham SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);
21830fdc8d8SChris Lattner }
21930fdc8d8SChris Lattner
ClearCallback()220b9c1b51eSKate Stone void BreakpointLocation::ClearCallback() {
221cfb96d84SJim Ingham GetLocationOptions().ClearCallback();
22230fdc8d8SChris Lattner }
22330fdc8d8SChris Lattner
SetCondition(const char * condition)224b9c1b51eSKate Stone void BreakpointLocation::SetCondition(const char *condition) {
225cfb96d84SJim Ingham GetLocationOptions().SetCondition(condition);
226e6bc6cb9SJim Ingham SendBreakpointLocationChangedEvent(eBreakpointEventTypeConditionChanged);
22736f3b369SJim Ingham }
22836f3b369SJim Ingham
GetConditionText(size_t * hash) const229b9c1b51eSKate Stone const char *BreakpointLocation::GetConditionText(size_t *hash) const {
230af26b22cSJim Ingham return GetOptionsSpecifyingKind(BreakpointOptions::eCondition)
231cfb96d84SJim Ingham .GetConditionText(hash);
2323dbf346eSSean Callanan }
2333dbf346eSSean Callanan
ConditionSaysStop(ExecutionContext & exe_ctx,Status & error)234b9c1b51eSKate Stone bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,
23597206d57SZachary Turner Status &error) {
236a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Breakpoints);
2373dbf346eSSean Callanan
238bb19a13cSSaleem Abdulrasool std::lock_guard<std::mutex> guard(m_condition_mutex);
239b4987e32SSean Callanan
2403dbf346eSSean Callanan size_t condition_hash;
2413dbf346eSSean Callanan const char *condition_text = GetConditionText(&condition_hash);
2423dbf346eSSean Callanan
243b9c1b51eSKate Stone if (!condition_text) {
244ec537a24SSean Callanan m_user_expression_sp.reset();
2453dbf346eSSean Callanan return false;
246ec537a24SSean Callanan }
2473dbf346eSSean Callanan
248298de8f6SJim Ingham error.Clear();
249298de8f6SJim Ingham
250579e70c9SSean Callanan DiagnosticManager diagnostics;
251579e70c9SSean Callanan
252b9c1b51eSKate Stone if (condition_hash != m_condition_hash || !m_user_expression_sp ||
253b9c1b51eSKate Stone !m_user_expression_sp->MatchesContext(exe_ctx)) {
254151c032cSJim Ingham LanguageType language = eLanguageTypeUnknown;
255b9c1b51eSKate Stone // See if we can figure out the language from the frame, otherwise use the
256b9c1b51eSKate Stone // default language:
257151c032cSJim Ingham CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit();
258151c032cSJim Ingham if (comp_unit)
259151c032cSJim Ingham language = comp_unit->GetLanguage();
260151c032cSJim Ingham
261b9c1b51eSKate Stone m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(
262c5d7df90SZachary Turner condition_text, llvm::StringRef(), language, Expression::eResultTypeAny,
26340624a08SAleksandr Urakov EvaluateExpressionOptions(), nullptr, error));
264b9c1b51eSKate Stone if (error.Fail()) {
26563e5fb76SJonas Devlieghere LLDB_LOGF(log, "Error getting condition expression: %s.",
266b9c1b51eSKate Stone error.AsCString());
267151c032cSJim Ingham m_user_expression_sp.reset();
268151c032cSJim Ingham return true;
269151c032cSJim Ingham }
270151c032cSJim Ingham
271b9c1b51eSKate Stone if (!m_user_expression_sp->Parse(diagnostics, exe_ctx,
272b9c1b51eSKate Stone eExecutionPolicyOnlyWhenNeeded, true,
273b9c1b51eSKate Stone false)) {
274b9c1b51eSKate Stone error.SetErrorStringWithFormat(
275b9c1b51eSKate Stone "Couldn't parse conditional expression:\n%s",
276579e70c9SSean Callanan diagnostics.GetString().c_str());
2773dbf346eSSean Callanan m_user_expression_sp.reset();
278298de8f6SJim Ingham return true;
2793dbf346eSSean Callanan }
2803dbf346eSSean Callanan
2813dbf346eSSean Callanan m_condition_hash = condition_hash;
2823dbf346eSSean Callanan }
2833dbf346eSSean Callanan
284b9c1b51eSKate Stone // We need to make sure the user sees any parse errors in their condition, so
28505097246SAdrian Prantl // we'll hook the constructor errors up to the debugger's Async I/O.
2863dbf346eSSean Callanan
2873dbf346eSSean Callanan ValueObjectSP result_value_sp;
28862afb9f6SGreg Clayton
28962afb9f6SGreg Clayton EvaluateExpressionOptions options;
29062afb9f6SGreg Clayton options.SetUnwindOnError(true);
29162afb9f6SGreg Clayton options.SetIgnoreBreakpoints(true);
2926fbc48bcSJim Ingham options.SetTryAllThreads(true);
293b9c1b51eSKate Stone options.SetResultIsInternal(
294b9c1b51eSKate Stone true); // Don't generate a user variable for condition expressions.
2953dbf346eSSean Callanan
29697206d57SZachary Turner Status expr_error;
2973dbf346eSSean Callanan
298579e70c9SSean Callanan diagnostics.Clear();
2993dbf346eSSean Callanan
300bc8ac34eSSean Callanan ExpressionVariableSP result_variable_sp;
3013dbf346eSSean Callanan
302b9c1b51eSKate Stone ExpressionResults result_code = m_user_expression_sp->Execute(
303b9c1b51eSKate Stone diagnostics, exe_ctx, options, m_user_expression_sp, result_variable_sp);
3043dbf346eSSean Callanan
3053dbf346eSSean Callanan bool ret;
3063dbf346eSSean Callanan
307b9c1b51eSKate Stone if (result_code == eExpressionCompleted) {
308b9c1b51eSKate Stone if (!result_variable_sp) {
309467441d5SSean Callanan error.SetErrorString("Expression did not return a result");
310879425faSSean Callanan return false;
311467441d5SSean Callanan }
312467441d5SSean Callanan
3133dbf346eSSean Callanan result_value_sp = result_variable_sp->GetValueObject();
3143dbf346eSSean Callanan
315b9c1b51eSKate Stone if (result_value_sp) {
31698e6daf1SJim Ingham ret = result_value_sp->IsLogicalTrue(error);
317b9c1b51eSKate Stone if (log) {
318b9c1b51eSKate Stone if (error.Success()) {
31963e5fb76SJonas Devlieghere LLDB_LOGF(log, "Condition successfully evaluated, result is %s.\n",
3203dbf346eSSean Callanan ret ? "true" : "false");
321b9c1b51eSKate Stone } else {
322b9c1b51eSKate Stone error.SetErrorString(
323b9c1b51eSKate Stone "Failed to get an integer result from the expression");
32498e6daf1SJim Ingham ret = false;
32598e6daf1SJim Ingham }
3263dbf346eSSean Callanan }
327b9c1b51eSKate Stone } else {
3283dbf346eSSean Callanan ret = false;
3293dbf346eSSean Callanan error.SetErrorString("Failed to get any result from the expression");
3303dbf346eSSean Callanan }
331b9c1b51eSKate Stone } else {
3323dbf346eSSean Callanan ret = false;
333b9c1b51eSKate Stone error.SetErrorStringWithFormat("Couldn't execute expression:\n%s",
334b9c1b51eSKate Stone diagnostics.GetString().c_str());
3353dbf346eSSean Callanan }
3363dbf346eSSean Callanan
3373dbf346eSSean Callanan return ret;
33836f3b369SJim Ingham }
33936f3b369SJim Ingham
GetIgnoreCount() const340da0bba5cSTatyana Krasnukha uint32_t BreakpointLocation::GetIgnoreCount() const {
341af26b22cSJim Ingham return GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
342cfb96d84SJim Ingham .GetIgnoreCount();
34330fdc8d8SChris Lattner }
34430fdc8d8SChris Lattner
SetIgnoreCount(uint32_t n)345b9c1b51eSKate Stone void BreakpointLocation::SetIgnoreCount(uint32_t n) {
346cfb96d84SJim Ingham GetLocationOptions().SetIgnoreCount(n);
347e6bc6cb9SJim Ingham SendBreakpointLocationChangedEvent(eBreakpointEventTypeIgnoreChanged);
34830fdc8d8SChris Lattner }
34930fdc8d8SChris Lattner
DecrementIgnoreCount()350b9c1b51eSKate Stone void BreakpointLocation::DecrementIgnoreCount() {
351d5b44036SJonas Devlieghere if (m_options_up != nullptr) {
352d5b44036SJonas Devlieghere uint32_t loc_ignore = m_options_up->GetIgnoreCount();
3530fd1b75fSJim Ingham if (loc_ignore != 0)
354d5b44036SJonas Devlieghere m_options_up->SetIgnoreCount(loc_ignore - 1);
3550fd1b75fSJim Ingham }
3560fd1b75fSJim Ingham }
3570fd1b75fSJim Ingham
IgnoreCountShouldStop()358b9c1b51eSKate Stone bool BreakpointLocation::IgnoreCountShouldStop() {
359658f6ed1SJim Ingham uint32_t owner_ignore = GetBreakpoint().GetIgnoreCount();
360658f6ed1SJim Ingham uint32_t loc_ignore = 0;
361658f6ed1SJim Ingham if (m_options_up != nullptr)
362658f6ed1SJim Ingham loc_ignore = m_options_up->GetIgnoreCount();
363658f6ed1SJim Ingham
364658f6ed1SJim Ingham if (loc_ignore != 0 || owner_ignore != 0) {
3650fd1b75fSJim Ingham m_owner.DecrementIgnoreCount();
366b9c1b51eSKate Stone DecrementIgnoreCount(); // Have to decrement our owners' ignore count,
367658f6ed1SJim Ingham // since it won't get a chance to.
3680fd1b75fSJim Ingham return false;
3690fd1b75fSJim Ingham }
3700fd1b75fSJim Ingham return true;
3710fd1b75fSJim Ingham }
3720fd1b75fSJim Ingham
GetLocationOptions()373cfb96d84SJim Ingham BreakpointOptions &BreakpointLocation::GetLocationOptions() {
37405097246SAdrian Prantl // If we make the copy we don't copy the callbacks because that is
37505097246SAdrian Prantl // potentially expensive and we don't want to do that for the simple case
37605097246SAdrian Prantl // where someone is just disabling the location.
377d5b44036SJonas Devlieghere if (m_options_up == nullptr)
37806412daeSJonas Devlieghere m_options_up = std::make_unique<BreakpointOptions>(false);
37930fdc8d8SChris Lattner
380cfb96d84SJim Ingham return *m_options_up;
38130fdc8d8SChris Lattner }
38230fdc8d8SChris Lattner
ValidForThisThread(Thread & thread)383cfb96d84SJim Ingham bool BreakpointLocation::ValidForThisThread(Thread &thread) {
384cfb96d84SJim Ingham return thread.MatchesSpec(
385cfb96d84SJim Ingham GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
386cfb96d84SJim Ingham .GetThreadSpecNoCreate());
3871b54c88cSJim Ingham }
3881b54c88cSJim Ingham
38930fdc8d8SChris Lattner // RETURNS - true if we should stop at this breakpoint, false if we
3901b54c88cSJim Ingham // should continue. Note, we don't check the thread spec for the breakpoint
3911b54c88cSJim Ingham // here, since if the breakpoint is not for this thread, then the event won't
3921b54c88cSJim Ingham // even get reported, so the check is redundant.
39330fdc8d8SChris Lattner
ShouldStop(StoppointCallbackContext * context)394b9c1b51eSKate Stone bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) {
39530fdc8d8SChris Lattner bool should_stop = true;
396a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Breakpoints);
39730fdc8d8SChris Lattner
398b9c1b51eSKate Stone // Do this first, if a location is disabled, it shouldn't increment its hit
399b9c1b51eSKate Stone // count.
40030fdc8d8SChris Lattner if (!IsEnabled())
40130fdc8d8SChris Lattner return false;
40230fdc8d8SChris Lattner
40336f3b369SJim Ingham // We only run synchronous callbacks in ShouldStop:
40430fdc8d8SChris Lattner context->is_synchronous = true;
40530fdc8d8SChris Lattner should_stop = InvokeCallback(context);
40630fdc8d8SChris Lattner
407b9c1b51eSKate Stone if (log) {
40830fdc8d8SChris Lattner StreamString s;
40930fdc8d8SChris Lattner GetDescription(&s, lldb::eDescriptionLevelVerbose);
41063e5fb76SJonas Devlieghere LLDB_LOGF(log, "Hit breakpoint location: %s, %s.\n", s.GetData(),
411b9c1b51eSKate Stone should_stop ? "stopping" : "continuing");
41230fdc8d8SChris Lattner }
4135b52f0c7SJim Ingham
41430fdc8d8SChris Lattner return should_stop;
41530fdc8d8SChris Lattner }
41630fdc8d8SChris Lattner
BumpHitCount()417b9c1b51eSKate Stone void BreakpointLocation::BumpHitCount() {
418b9c1b51eSKate Stone if (IsEnabled()) {
419d762df8cSJim Ingham // Step our hit count, and also step the hit count of the owner.
420da0bba5cSTatyana Krasnukha m_hit_counter.Increment();
421da0bba5cSTatyana Krasnukha m_owner.m_hit_counter.Increment();
422d762df8cSJim Ingham }
423d762df8cSJim Ingham }
424d762df8cSJim Ingham
UndoBumpHitCount()425b9c1b51eSKate Stone void BreakpointLocation::UndoBumpHitCount() {
426b9c1b51eSKate Stone if (IsEnabled()) {
427d762df8cSJim Ingham // Step our hit count, and also step the hit count of the owner.
428da0bba5cSTatyana Krasnukha m_hit_counter.Decrement();
429da0bba5cSTatyana Krasnukha m_owner.m_hit_counter.Decrement();
430d762df8cSJim Ingham }
431a672ecefSJim Ingham }
432a672ecefSJim Ingham
IsResolved() const433b9c1b51eSKate Stone bool BreakpointLocation::IsResolved() const {
43416fd7511SEugene Zelenko return m_bp_site_sp.get() != nullptr;
43530fdc8d8SChris Lattner }
43630fdc8d8SChris Lattner
GetBreakpointSite() const437b9c1b51eSKate Stone lldb::BreakpointSiteSP BreakpointLocation::GetBreakpointSite() const {
43836f3b369SJim Ingham return m_bp_site_sp;
43936f3b369SJim Ingham }
44036f3b369SJim Ingham
ResolveBreakpointSite()441b9c1b51eSKate Stone bool BreakpointLocation::ResolveBreakpointSite() {
44230fdc8d8SChris Lattner if (m_bp_site_sp)
44330fdc8d8SChris Lattner return true;
44430fdc8d8SChris Lattner
44530fdc8d8SChris Lattner Process *process = m_owner.GetTarget().GetProcessSP().get();
44616fd7511SEugene Zelenko if (process == nullptr)
44730fdc8d8SChris Lattner return false;
44830fdc8d8SChris Lattner
449b9c1b51eSKate Stone lldb::break_id_t new_id =
450b9c1b51eSKate Stone process->CreateBreakpointSite(shared_from_this(), m_owner.IsHardware());
45130fdc8d8SChris Lattner
452b9c1b51eSKate Stone if (new_id == LLDB_INVALID_BREAK_ID) {
453a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Breakpoints);
45430fdc8d8SChris Lattner if (log)
455414f9b30STatyana Krasnukha log->Warning("Failed to add breakpoint site at 0x%" PRIx64,
456f3ef3d2aSGreg Clayton m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()));
45730fdc8d8SChris Lattner }
45830fdc8d8SChris Lattner
459414f9b30STatyana Krasnukha return IsResolved();
46030fdc8d8SChris Lattner }
46130fdc8d8SChris Lattner
SetBreakpointSite(BreakpointSiteSP & bp_site_sp)462b9c1b51eSKate Stone bool BreakpointLocation::SetBreakpointSite(BreakpointSiteSP &bp_site_sp) {
46330fdc8d8SChris Lattner m_bp_site_sp = bp_site_sp;
4649b618d25SIlia K SendBreakpointLocationChangedEvent(eBreakpointEventTypeLocationsResolved);
46530fdc8d8SChris Lattner return true;
46630fdc8d8SChris Lattner }
46730fdc8d8SChris Lattner
ClearBreakpointSite()468b9c1b51eSKate Stone bool BreakpointLocation::ClearBreakpointSite() {
469b9c1b51eSKate Stone if (m_bp_site_sp.get()) {
47015783131SJim Ingham ProcessSP process_sp(m_owner.GetTarget().GetProcessSP());
471b9c1b51eSKate Stone // If the process exists, get it to remove the owner, it will remove the
47205097246SAdrian Prantl // physical implementation of the breakpoint as well if there are no more
47305097246SAdrian Prantl // owners. Otherwise just remove this owner.
47415783131SJim Ingham if (process_sp)
47515783131SJim Ingham process_sp->RemoveOwnerFromBreakpointSite(GetBreakpoint().GetID(),
4760136309fSJim Ingham GetID(), m_bp_site_sp);
47715783131SJim Ingham else
47815783131SJim Ingham m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID());
47915783131SJim Ingham
48030fdc8d8SChris Lattner m_bp_site_sp.reset();
48130fdc8d8SChris Lattner return true;
48230fdc8d8SChris Lattner }
48330fdc8d8SChris Lattner return false;
48430fdc8d8SChris Lattner }
48530fdc8d8SChris Lattner
GetDescription(Stream * s,lldb::DescriptionLevel level)486b9c1b51eSKate Stone void BreakpointLocation::GetDescription(Stream *s,
487b9c1b51eSKate Stone lldb::DescriptionLevel level) {
48830fdc8d8SChris Lattner SymbolContext sc;
4891391cc7dSJim Ingham
490b9c1b51eSKate Stone // If the description level is "initial" then the breakpoint is printing out
49105097246SAdrian Prantl // our initial state, and we should let it decide how it wants to print our
49205097246SAdrian Prantl // label.
493b9c1b51eSKate Stone if (level != eDescriptionLevelInitial) {
49430fdc8d8SChris Lattner s->Indent();
49530fdc8d8SChris Lattner BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
4961391cc7dSJim Ingham }
49730fdc8d8SChris Lattner
49830fdc8d8SChris Lattner if (level == lldb::eDescriptionLevelBrief)
49930fdc8d8SChris Lattner return;
50030fdc8d8SChris Lattner
5011391cc7dSJim Ingham if (level != eDescriptionLevelInitial)
50230fdc8d8SChris Lattner s->PutCString(": ");
50330fdc8d8SChris Lattner
50430fdc8d8SChris Lattner if (level == lldb::eDescriptionLevelVerbose)
50530fdc8d8SChris Lattner s->IndentMore();
50630fdc8d8SChris Lattner
507b9c1b51eSKate Stone if (m_address.IsSectionOffset()) {
50830fdc8d8SChris Lattner m_address.CalculateSymbolContext(&sc);
50930fdc8d8SChris Lattner
510b9c1b51eSKate Stone if (level == lldb::eDescriptionLevelFull ||
511b9c1b51eSKate Stone level == eDescriptionLevelInitial) {
5121460e4bfSJim Ingham if (IsReExported())
5131460e4bfSJim Ingham s->PutCString("re-exported target = ");
5141460e4bfSJim Ingham else
51530fdc8d8SChris Lattner s->PutCString("where = ");
516b9c1b51eSKate Stone sc.DumpStopContext(s, m_owner.GetTarget().GetProcessSP().get(), m_address,
517b9c1b51eSKate Stone false, true, false, true, true);
518b9c1b51eSKate Stone } else {
519b9c1b51eSKate Stone if (sc.module_sp) {
52030fdc8d8SChris Lattner s->EOL();
52130fdc8d8SChris Lattner s->Indent("module = ");
5224dac97ebSRaphael Isemann sc.module_sp->GetFileSpec().Dump(s->AsRawOstream());
52330fdc8d8SChris Lattner }
52430fdc8d8SChris Lattner
525b9c1b51eSKate Stone if (sc.comp_unit != nullptr) {
52630fdc8d8SChris Lattner s->EOL();
52730fdc8d8SChris Lattner s->Indent("compile unit = ");
52838870af8SPavel Labath sc.comp_unit->GetPrimaryFile().GetFilename().Dump(s);
52930fdc8d8SChris Lattner
530b9c1b51eSKate Stone if (sc.function != nullptr) {
53130fdc8d8SChris Lattner s->EOL();
53230fdc8d8SChris Lattner s->Indent("function = ");
533ddaf6a72SGreg Clayton s->PutCString(sc.function->GetName().AsCString("<unknown>"));
53430fdc8d8SChris Lattner }
53530fdc8d8SChris Lattner
536b9c1b51eSKate Stone if (sc.line_entry.line > 0) {
53730fdc8d8SChris Lattner s->EOL();
53830fdc8d8SChris Lattner s->Indent("location = ");
5396dadd508SGreg Clayton sc.line_entry.DumpStopContext(s, true);
54030fdc8d8SChris Lattner }
54130fdc8d8SChris Lattner
542b9c1b51eSKate Stone } else {
54330fdc8d8SChris Lattner // If we don't have a comp unit, see if we have a symbol we can print.
544b9c1b51eSKate Stone if (sc.symbol) {
54530fdc8d8SChris Lattner s->EOL();
5461460e4bfSJim Ingham if (IsReExported())
5471460e4bfSJim Ingham s->Indent("re-exported target = ");
5481460e4bfSJim Ingham else
54930fdc8d8SChris Lattner s->Indent("symbol = ");
550ddaf6a72SGreg Clayton s->PutCString(sc.symbol->GetName().AsCString("<unknown>"));
55130fdc8d8SChris Lattner }
55230fdc8d8SChris Lattner }
55330fdc8d8SChris Lattner }
55430fdc8d8SChris Lattner }
55530fdc8d8SChris Lattner
556b9c1b51eSKate Stone if (level == lldb::eDescriptionLevelVerbose) {
55730fdc8d8SChris Lattner s->EOL();
55830fdc8d8SChris Lattner s->Indent();
55930fdc8d8SChris Lattner }
5601391cc7dSJim Ingham
561b9c1b51eSKate Stone if (m_address.IsSectionOffset() &&
562b9c1b51eSKate Stone (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
5631391cc7dSJim Ingham s->Printf(", ");
5641391cc7dSJim Ingham s->Printf("address = ");
5651391cc7dSJim Ingham
56616fd7511SEugene Zelenko ExecutionContextScope *exe_scope = nullptr;
56730fdc8d8SChris Lattner Target *target = &m_owner.GetTarget();
56830fdc8d8SChris Lattner if (target)
56930fdc8d8SChris Lattner exe_scope = target->GetProcessSP().get();
57016fd7511SEugene Zelenko if (exe_scope == nullptr)
57130fdc8d8SChris Lattner exe_scope = target;
57230fdc8d8SChris Lattner
5738f632665SJim Ingham if (level == eDescriptionLevelInitial)
574b9c1b51eSKate Stone m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
575b9c1b51eSKate Stone Address::DumpStyleFileAddress);
5761391cc7dSJim Ingham else
577b9c1b51eSKate Stone m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
578b9c1b51eSKate Stone Address::DumpStyleModuleWithFileAddress);
57930fdc8d8SChris Lattner
580b9c1b51eSKate Stone if (IsIndirect() && m_bp_site_sp) {
5811460e4bfSJim Ingham Address resolved_address;
5821460e4bfSJim Ingham resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
5831460e4bfSJim Ingham Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
584b9c1b51eSKate Stone if (resolved_symbol) {
5851460e4bfSJim Ingham if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
5861460e4bfSJim Ingham s->Printf(", ");
587b9c1b51eSKate Stone else if (level == lldb::eDescriptionLevelVerbose) {
5881460e4bfSJim Ingham s->EOL();
5891460e4bfSJim Ingham s->Indent();
5901460e4bfSJim Ingham }
591b9c1b51eSKate Stone s->Printf("indirect target = %s",
592b9c1b51eSKate Stone resolved_symbol->GetName().GetCString());
5931460e4bfSJim Ingham }
5941460e4bfSJim Ingham }
5951460e4bfSJim Ingham
596da0bba5cSTatyana Krasnukha bool is_resolved = IsResolved();
597da0bba5cSTatyana Krasnukha bool is_hardware = is_resolved && m_bp_site_sp->IsHardware();
598da0bba5cSTatyana Krasnukha
599b9c1b51eSKate Stone if (level == lldb::eDescriptionLevelVerbose) {
60030fdc8d8SChris Lattner s->EOL();
60130fdc8d8SChris Lattner s->Indent();
602da0bba5cSTatyana Krasnukha s->Printf("resolved = %s\n", is_resolved ? "true" : "false");
603d8e0f4faSJonas Devlieghere s->Indent();
604da0bba5cSTatyana Krasnukha s->Printf("hardware = %s\n", is_hardware ? "true" : "false");
60530fdc8d8SChris Lattner s->Indent();
60630fdc8d8SChris Lattner s->Printf("hit count = %-4u\n", GetHitCount());
60730fdc8d8SChris Lattner
608d5b44036SJonas Devlieghere if (m_options_up) {
60930fdc8d8SChris Lattner s->Indent();
610d5b44036SJonas Devlieghere m_options_up->GetDescription(s, level);
61130fdc8d8SChris Lattner s->EOL();
61230fdc8d8SChris Lattner }
61330fdc8d8SChris Lattner s->IndentLess();
614b9c1b51eSKate Stone } else if (level != eDescriptionLevelInitial) {
615da0bba5cSTatyana Krasnukha s->Printf(", %sresolved, %shit count = %u ", (is_resolved ? "" : "un"),
616da0bba5cSTatyana Krasnukha (is_hardware ? "hardware, " : ""), GetHitCount());
617d5b44036SJonas Devlieghere if (m_options_up) {
618d5b44036SJonas Devlieghere m_options_up->GetDescription(s, level);
6190136309fSJim Ingham }
62030fdc8d8SChris Lattner }
62130fdc8d8SChris Lattner }
62230fdc8d8SChris Lattner
Dump(Stream * s) const623b9c1b51eSKate Stone void BreakpointLocation::Dump(Stream *s) const {
62416fd7511SEugene Zelenko if (s == nullptr)
62530fdc8d8SChris Lattner return;
62630fdc8d8SChris Lattner
627da0bba5cSTatyana Krasnukha bool is_resolved = IsResolved();
628da0bba5cSTatyana Krasnukha bool is_hardware = is_resolved && m_bp_site_sp->IsHardware();
629da0bba5cSTatyana Krasnukha auto hardware_index = is_resolved ?
630da0bba5cSTatyana Krasnukha m_bp_site_sp->GetHardwareIndex() : LLDB_INVALID_INDEX32;
631da0bba5cSTatyana Krasnukha
632af26b22cSJim Ingham lldb::tid_t tid = GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
633cfb96d84SJim Ingham .GetThreadSpecNoCreate()
634cfb96d84SJim Ingham ->GetTID();
63570355aceSJonas Devlieghere s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64
63670355aceSJonas Devlieghere " load addr = 0x%8.8" PRIx64 " state = %s type = %s breakpoint "
6370136309fSJim Ingham "hw_index = %i hit_count = %-4u ignore_count = %-4u",
638af26b22cSJim Ingham GetID(), tid,
639f3ef3d2aSGreg Clayton (uint64_t)m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()),
640d5b44036SJonas Devlieghere (m_options_up ? m_options_up->IsEnabled() : m_owner.IsEnabled())
641b9c1b51eSKate Stone ? "enabled "
642b9c1b51eSKate Stone : "disabled",
643cfb96d84SJim Ingham is_hardware ? "hardware" : "software", hardware_index,
644cfb96d84SJim Ingham GetHitCount(),
645af26b22cSJim Ingham GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
646cfb96d84SJim Ingham .GetIgnoreCount());
64730fdc8d8SChris Lattner }
648e6bc6cb9SJim Ingham
SendBreakpointLocationChangedEvent(lldb::BreakpointEventType eventKind)649b9c1b51eSKate Stone void BreakpointLocation::SendBreakpointLocationChangedEvent(
650b9c1b51eSKate Stone lldb::BreakpointEventType eventKind) {
651b9c1b51eSKate Stone if (!m_being_created && !m_owner.IsInternal() &&
652b9c1b51eSKate Stone m_owner.GetTarget().EventTypeHasListeners(
653b9c1b51eSKate Stone Target::eBroadcastBitBreakpointChanged)) {
654b9c1b51eSKate Stone Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData(
655b9c1b51eSKate Stone eventKind, m_owner.shared_from_this());
656e6bc6cb9SJim Ingham data->GetBreakpointLocationCollection().Add(shared_from_this());
657b9c1b51eSKate Stone m_owner.GetTarget().BroadcastEvent(Target::eBroadcastBitBreakpointChanged,
658b9c1b51eSKate Stone data);
659e6bc6cb9SJim Ingham }
660e6bc6cb9SJim Ingham }
661e6bc6cb9SJim Ingham
SwapLocation(BreakpointLocationSP swap_from)662b9c1b51eSKate Stone void BreakpointLocation::SwapLocation(BreakpointLocationSP swap_from) {
66377fd738fSJim Ingham m_address = swap_from->m_address;
664b9c1b51eSKate Stone m_should_resolve_indirect_functions =
665b9c1b51eSKate Stone swap_from->m_should_resolve_indirect_functions;
66677fd738fSJim Ingham m_is_reexported = swap_from->m_is_reexported;
66777fd738fSJim Ingham m_is_indirect = swap_from->m_is_indirect;
66877fd738fSJim Ingham m_user_expression_sp.reset();
66977fd738fSJim Ingham }
670