blob: 932147703304da881e94d1bd18c36113ed262617 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- BreakpointLocation.cpp ----------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
11// C++ Includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012// Other libraries and framework includes
13// Project includes
14#include "lldb/Breakpoint/BreakpointLocation.h"
15#include "lldb/Breakpoint/BreakpointID.h"
16#include "lldb/Breakpoint/StoppointCallbackContext.h"
Jim Ingham5b52f0c2011-06-02 23:58:26 +000017#include "lldb/Core/Debugger.h"
Greg Clayton1f746072012-08-29 21:13:06 +000018#include "lldb/Core/Module.h"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000019#include "lldb/Core/ValueObject.h"
Sean Callanan579e70c2016-03-19 00:03:59 +000020#include "lldb/Expression/DiagnosticManager.h"
Bruce Mitchener937e3962015-09-21 16:56:08 +000021#include "lldb/Expression/ExpressionVariable.h"
Jim Ingham151c0322015-09-15 21:13:50 +000022#include "lldb/Expression/UserExpression.h"
Greg Clayton1f746072012-08-29 21:13:06 +000023#include "lldb/Symbol/CompileUnit.h"
24#include "lldb/Symbol/Symbol.h"
Jim Ingham151c0322015-09-15 21:13:50 +000025#include "lldb/Symbol/TypeSystem.h"
Greg Clayton1f746072012-08-29 21:13:06 +000026#include "lldb/Target/Process.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000027#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028#include "lldb/Target/Thread.h"
Jim Ingham1b54c882010-06-16 02:00:15 +000029#include "lldb/Target/ThreadSpec.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000030#include "lldb/Utility/Log.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000031#include "lldb/Utility/StreamString.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032
33using namespace lldb;
34using namespace lldb_private;
35
Kate Stoneb9c1b512016-09-06 20:57:50 +000036BreakpointLocation::BreakpointLocation(break_id_t loc_id, Breakpoint &owner,
37 const Address &addr, lldb::tid_t tid,
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +000038 bool hardware, bool check_for_resolver)
Kate Stoneb9c1b512016-09-06 20:57:50 +000039 : StoppointLocation(loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()),
40 hardware),
41 m_being_created(true), m_should_resolve_indirect_functions(false),
42 m_is_reexported(false), m_is_indirect(false), m_address(addr),
43 m_owner(owner), m_options_ap(), m_bp_site_sp(), m_condition_mutex() {
44 if (check_for_resolver) {
45 Symbol *symbol = m_address.CalculateSymbolContextSymbol();
46 if (symbol && symbol->IsIndirect()) {
47 SetShouldResolveIndirectFunctions(true);
Jim Ingham1460e4b2014-01-10 23:46:59 +000048 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000049 }
Saleem Abdulrasoolbb19a132016-05-19 05:13:57 +000050
Kate Stoneb9c1b512016-09-06 20:57:50 +000051 SetThreadID(tid);
52 m_being_created = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000053}
54
Kate Stoneb9c1b512016-09-06 20:57:50 +000055BreakpointLocation::~BreakpointLocation() { ClearBreakpointSite(); }
56
57lldb::addr_t BreakpointLocation::GetLoadAddress() const {
58 return m_address.GetOpcodeLoadAddress(&m_owner.GetTarget());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000059}
60
Jim Inghamaf26b222017-08-02 00:16:10 +000061const BreakpointOptions *
62BreakpointLocation::GetOptionsSpecifyingKind(BreakpointOptions::OptionKind kind)
63const {
64 if (m_options_ap && m_options_ap->IsOptionSet(kind))
65 return m_options_ap.get();
66 else
67 return m_owner.GetOptions();
68}
69
Kate Stoneb9c1b512016-09-06 20:57:50 +000070Address &BreakpointLocation::GetAddress() { return m_address; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000071
Kate Stoneb9c1b512016-09-06 20:57:50 +000072Breakpoint &BreakpointLocation::GetBreakpoint() { return m_owner; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073
Kate Stoneb9c1b512016-09-06 20:57:50 +000074Target &BreakpointLocation::GetTarget() { return m_owner.GetTarget(); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000075
Kate Stoneb9c1b512016-09-06 20:57:50 +000076bool BreakpointLocation::IsEnabled() const {
77 if (!m_owner.IsEnabled())
78 return false;
79 else if (m_options_ap.get() != nullptr)
80 return m_options_ap->IsEnabled();
81 else
Jim Ingham0fd1b752012-06-26 22:27:55 +000082 return true;
83}
84
Kate Stoneb9c1b512016-09-06 20:57:50 +000085void BreakpointLocation::SetEnabled(bool enabled) {
86 GetLocationOptions()->SetEnabled(enabled);
87 if (enabled) {
88 ResolveBreakpointSite();
89 } else {
90 ClearBreakpointSite();
91 }
92 SendBreakpointLocationChangedEvent(enabled ? eBreakpointEventTypeEnabled
93 : eBreakpointEventTypeDisabled);
94}
95
Jim Inghamf08f5c92017-08-03 18:13:24 +000096bool BreakpointLocation::IsAutoContinue() const {
97 if (m_options_ap
98 && m_options_ap->IsOptionSet(BreakpointOptions::eAutoContinue))
99 return m_options_ap->IsAutoContinue();
100 else
101 return m_owner.IsAutoContinue();
102}
103
104void BreakpointLocation::SetAutoContinue(bool auto_continue) {
105 GetLocationOptions()->SetAutoContinue(auto_continue);
106 SendBreakpointLocationChangedEvent(eBreakpointEventTypeAutoContinueChanged);
107}
108
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) {
110 if (thread_id != LLDB_INVALID_THREAD_ID)
111 GetLocationOptions()->SetThreadID(thread_id);
112 else {
Adrian Prantl05097242018-04-30 16:49:04 +0000113 // If we're resetting this to an invalid thread id, then don't make an
114 // options pointer just to do that.
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000115 if (m_options_ap.get() != nullptr)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000116 m_options_ap->SetThreadID(thread_id);
117 }
118 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000119}
120
Kate Stoneb9c1b512016-09-06 20:57:50 +0000121lldb::tid_t BreakpointLocation::GetThreadID() {
Jim Inghamaf26b222017-08-02 00:16:10 +0000122 const ThreadSpec *thread_spec =
123 GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
124 ->GetThreadSpecNoCreate();
125 if (thread_spec)
126 return thread_spec->GetTID();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000127 else
128 return LLDB_INVALID_THREAD_ID;
129}
130
131void BreakpointLocation::SetThreadIndex(uint32_t index) {
132 if (index != 0)
133 GetLocationOptions()->GetThreadSpec()->SetIndex(index);
134 else {
Adrian Prantl05097242018-04-30 16:49:04 +0000135 // If we're resetting this to an invalid thread id, then don't make an
136 // options pointer just to do that.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137 if (m_options_ap.get() != nullptr)
138 m_options_ap->GetThreadSpec()->SetIndex(index);
139 }
140 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
141}
142
143uint32_t BreakpointLocation::GetThreadIndex() const {
Jim Inghamaf26b222017-08-02 00:16:10 +0000144 const ThreadSpec *thread_spec =
145 GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
146 ->GetThreadSpecNoCreate();
147 if (thread_spec)
148 return thread_spec->GetIndex();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000149 else
150 return 0;
151}
152
153void BreakpointLocation::SetThreadName(const char *thread_name) {
154 if (thread_name != nullptr)
155 GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
156 else {
Adrian Prantl05097242018-04-30 16:49:04 +0000157 // If we're resetting this to an invalid thread id, then don't make an
158 // options pointer just to do that.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000159 if (m_options_ap.get() != nullptr)
160 m_options_ap->GetThreadSpec()->SetName(thread_name);
161 }
162 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
163}
164
165const char *BreakpointLocation::GetThreadName() const {
Jim Inghamaf26b222017-08-02 00:16:10 +0000166 const ThreadSpec *thread_spec =
167 GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
168 ->GetThreadSpecNoCreate();
169 if (thread_spec)
170 return thread_spec->GetName();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000171 else
172 return nullptr;
173}
174
175void BreakpointLocation::SetQueueName(const char *queue_name) {
176 if (queue_name != nullptr)
177 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
178 else {
Adrian Prantl05097242018-04-30 16:49:04 +0000179 // If we're resetting this to an invalid thread id, then don't make an
180 // options pointer just to do that.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000181 if (m_options_ap.get() != nullptr)
182 m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
183 }
184 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
185}
186
187const char *BreakpointLocation::GetQueueName() const {
Jim Inghamaf26b222017-08-02 00:16:10 +0000188 const ThreadSpec *thread_spec =
189 GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
190 ->GetThreadSpecNoCreate();
191 if (thread_spec)
192 return thread_spec->GetQueueName();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193 else
194 return nullptr;
195}
196
197bool BreakpointLocation::InvokeCallback(StoppointCallbackContext *context) {
198 if (m_options_ap.get() != nullptr && m_options_ap->HasCallback())
199 return m_options_ap->InvokeCallback(context, m_owner.GetID(), GetID());
200 else
201 return m_owner.InvokeCallback(context, GetID());
202}
203
204void BreakpointLocation::SetCallback(BreakpointHitCallback callback,
205 void *baton, bool is_synchronous) {
Adrian Prantl05097242018-04-30 16:49:04 +0000206 // The default "Baton" class will keep a copy of "baton" and won't free or
207 // delete it when it goes goes out of scope.
Zachary Turner4e4fbe82016-09-13 17:53:38 +0000208 GetLocationOptions()->SetCallback(
209 callback, std::make_shared<UntypedBaton>(baton), is_synchronous);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000210 SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);
211}
212
213void BreakpointLocation::SetCallback(BreakpointHitCallback callback,
214 const BatonSP &baton_sp,
215 bool is_synchronous) {
216 GetLocationOptions()->SetCallback(callback, baton_sp, is_synchronous);
217 SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);
218}
219
220void BreakpointLocation::ClearCallback() {
221 GetLocationOptions()->ClearCallback();
222}
223
224void BreakpointLocation::SetCondition(const char *condition) {
225 GetLocationOptions()->SetCondition(condition);
226 SendBreakpointLocationChangedEvent(eBreakpointEventTypeConditionChanged);
227}
228
229const char *BreakpointLocation::GetConditionText(size_t *hash) const {
Jim Inghamaf26b222017-08-02 00:16:10 +0000230 return GetOptionsSpecifyingKind(BreakpointOptions::eCondition)
231 ->GetConditionText(hash);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000232}
233
234bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,
Zachary Turner97206d52017-05-12 04:51:55 +0000235 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000236 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
237
238 std::lock_guard<std::mutex> guard(m_condition_mutex);
239
240 size_t condition_hash;
241 const char *condition_text = GetConditionText(&condition_hash);
242
243 if (!condition_text) {
244 m_user_expression_sp.reset();
245 return false;
246 }
247
248 error.Clear();
249
250 DiagnosticManager diagnostics;
251
252 if (condition_hash != m_condition_hash || !m_user_expression_sp ||
253 !m_user_expression_sp->MatchesContext(exe_ctx)) {
254 LanguageType language = eLanguageTypeUnknown;
255 // See if we can figure out the language from the frame, otherwise use the
256 // default language:
257 CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit();
258 if (comp_unit)
259 language = comp_unit->GetLanguage();
260
261 m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(
Zachary Turnerc5d7df92016-11-08 04:52:16 +0000262 condition_text, llvm::StringRef(), language, Expression::eResultTypeAny,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000263 EvaluateExpressionOptions(), error));
264 if (error.Fail()) {
265 if (log)
266 log->Printf("Error getting condition expression: %s.",
267 error.AsCString());
268 m_user_expression_sp.reset();
269 return true;
270 }
271
272 if (!m_user_expression_sp->Parse(diagnostics, exe_ctx,
273 eExecutionPolicyOnlyWhenNeeded, true,
274 false)) {
275 error.SetErrorStringWithFormat(
276 "Couldn't parse conditional expression:\n%s",
277 diagnostics.GetString().c_str());
278 m_user_expression_sp.reset();
279 return true;
280 }
281
282 m_condition_hash = condition_hash;
283 }
284
285 // We need to make sure the user sees any parse errors in their condition, so
Adrian Prantl05097242018-04-30 16:49:04 +0000286 // we'll hook the constructor errors up to the debugger's Async I/O.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000287
288 ValueObjectSP result_value_sp;
289
290 EvaluateExpressionOptions options;
291 options.SetUnwindOnError(true);
292 options.SetIgnoreBreakpoints(true);
293 options.SetTryAllThreads(true);
294 options.SetResultIsInternal(
295 true); // Don't generate a user variable for condition expressions.
296
Zachary Turner97206d52017-05-12 04:51:55 +0000297 Status expr_error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000298
299 diagnostics.Clear();
300
301 ExpressionVariableSP result_variable_sp;
302
303 ExpressionResults result_code = m_user_expression_sp->Execute(
304 diagnostics, exe_ctx, options, m_user_expression_sp, result_variable_sp);
305
306 bool ret;
307
308 if (result_code == eExpressionCompleted) {
309 if (!result_variable_sp) {
310 error.SetErrorString("Expression did not return a result");
311 return false;
312 }
313
314 result_value_sp = result_variable_sp->GetValueObject();
315
316 if (result_value_sp) {
317 ret = result_value_sp->IsLogicalTrue(error);
318 if (log) {
319 if (error.Success()) {
320 log->Printf("Condition successfully evaluated, result is %s.\n",
321 ret ? "true" : "false");
322 } else {
323 error.SetErrorString(
324 "Failed to get an integer result from the expression");
325 ret = false;
326 }
327 }
328 } else {
329 ret = false;
330 error.SetErrorString("Failed to get any result from the expression");
331 }
332 } else {
333 ret = false;
334 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s",
335 diagnostics.GetString().c_str());
336 }
337
338 return ret;
339}
340
341uint32_t BreakpointLocation::GetIgnoreCount() {
Jim Inghamaf26b222017-08-02 00:16:10 +0000342 return GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
343 ->GetIgnoreCount();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000344}
345
346void BreakpointLocation::SetIgnoreCount(uint32_t n) {
347 GetLocationOptions()->SetIgnoreCount(n);
348 SendBreakpointLocationChangedEvent(eBreakpointEventTypeIgnoreChanged);
349}
350
351void BreakpointLocation::DecrementIgnoreCount() {
352 if (m_options_ap.get() != nullptr) {
353 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
354 if (loc_ignore != 0)
355 m_options_ap->SetIgnoreCount(loc_ignore - 1);
356 }
357}
358
359bool BreakpointLocation::IgnoreCountShouldStop() {
360 if (m_options_ap.get() != nullptr) {
361 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
362 if (loc_ignore != 0) {
363 m_owner.DecrementIgnoreCount();
364 DecrementIgnoreCount(); // Have to decrement our owners' ignore count,
365 // since it won't get a
366 // chance to.
367 return false;
368 }
369 }
370 return true;
371}
372
Kate Stoneb9c1b512016-09-06 20:57:50 +0000373BreakpointOptions *BreakpointLocation::GetLocationOptions() {
Adrian Prantl05097242018-04-30 16:49:04 +0000374 // If we make the copy we don't copy the callbacks because that is
375 // potentially expensive and we don't want to do that for the simple case
376 // where someone is just disabling the location.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000377 if (m_options_ap.get() == nullptr)
378 m_options_ap.reset(
Jim Inghamaf26b222017-08-02 00:16:10 +0000379 new BreakpointOptions(false));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000380
381 return m_options_ap.get();
382}
383
384bool BreakpointLocation::ValidForThisThread(Thread *thread) {
Jim Inghamaf26b222017-08-02 00:16:10 +0000385 return thread
386 ->MatchesSpec(GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
387 ->GetThreadSpecNoCreate());
Jim Ingham1b54c882010-06-16 02:00:15 +0000388}
389
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390// RETURNS - true if we should stop at this breakpoint, false if we
Jim Ingham1b54c882010-06-16 02:00:15 +0000391// should continue. Note, we don't check the thread spec for the breakpoint
392// here, since if the breakpoint is not for this thread, then the event won't
393// even get reported, so the check is redundant.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000394
Kate Stoneb9c1b512016-09-06 20:57:50 +0000395bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) {
396 bool should_stop = true;
397 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000398
Kate Stoneb9c1b512016-09-06 20:57:50 +0000399 // Do this first, if a location is disabled, it shouldn't increment its hit
400 // count.
401 if (!IsEnabled())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000402 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000403
404 if (!IgnoreCountShouldStop())
405 return false;
406
407 if (!m_owner.IgnoreCountShouldStop())
408 return false;
409
410 // We only run synchronous callbacks in ShouldStop:
411 context->is_synchronous = true;
412 should_stop = InvokeCallback(context);
413
414 if (log) {
415 StreamString s;
416 GetDescription(&s, lldb::eDescriptionLevelVerbose);
417 log->Printf("Hit breakpoint location: %s, %s.\n", s.GetData(),
418 should_stop ? "stopping" : "continuing");
419 }
420
421 return should_stop;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000422}
423
Kate Stoneb9c1b512016-09-06 20:57:50 +0000424void BreakpointLocation::BumpHitCount() {
425 if (IsEnabled()) {
426 // Step our hit count, and also step the hit count of the owner.
427 IncrementHitCount();
428 m_owner.IncrementHitCount();
429 }
430}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000431
Kate Stoneb9c1b512016-09-06 20:57:50 +0000432void BreakpointLocation::UndoBumpHitCount() {
433 if (IsEnabled()) {
434 // Step our hit count, and also step the hit count of the owner.
435 DecrementHitCount();
436 m_owner.DecrementHitCount();
437 }
438}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000439
Kate Stoneb9c1b512016-09-06 20:57:50 +0000440bool BreakpointLocation::IsResolved() const {
441 return m_bp_site_sp.get() != nullptr;
442}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000443
Kate Stoneb9c1b512016-09-06 20:57:50 +0000444lldb::BreakpointSiteSP BreakpointLocation::GetBreakpointSite() const {
445 return m_bp_site_sp;
446}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000447
Kate Stoneb9c1b512016-09-06 20:57:50 +0000448bool BreakpointLocation::ResolveBreakpointSite() {
449 if (m_bp_site_sp)
450 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000451
Kate Stoneb9c1b512016-09-06 20:57:50 +0000452 Process *process = m_owner.GetTarget().GetProcessSP().get();
453 if (process == nullptr)
454 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000455
Kate Stoneb9c1b512016-09-06 20:57:50 +0000456 lldb::break_id_t new_id =
457 process->CreateBreakpointSite(shared_from_this(), m_owner.IsHardware());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000458
Kate Stoneb9c1b512016-09-06 20:57:50 +0000459 if (new_id == LLDB_INVALID_BREAK_ID) {
460 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
461 if (log)
462 log->Warning("Tried to add breakpoint site at 0x%" PRIx64
463 " but it was already present.\n",
464 m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()));
465 return false;
466 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000467
Kate Stoneb9c1b512016-09-06 20:57:50 +0000468 return true;
469}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000470
Kate Stoneb9c1b512016-09-06 20:57:50 +0000471bool BreakpointLocation::SetBreakpointSite(BreakpointSiteSP &bp_site_sp) {
472 m_bp_site_sp = bp_site_sp;
473 SendBreakpointLocationChangedEvent(eBreakpointEventTypeLocationsResolved);
474 return true;
475}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000476
Kate Stoneb9c1b512016-09-06 20:57:50 +0000477bool BreakpointLocation::ClearBreakpointSite() {
478 if (m_bp_site_sp.get()) {
479 ProcessSP process_sp(m_owner.GetTarget().GetProcessSP());
480 // If the process exists, get it to remove the owner, it will remove the
Adrian Prantl05097242018-04-30 16:49:04 +0000481 // physical implementation of the breakpoint as well if there are no more
482 // owners. Otherwise just remove this owner.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000483 if (process_sp)
484 process_sp->RemoveOwnerFromBreakpointSite(GetBreakpoint().GetID(),
485 GetID(), m_bp_site_sp);
Jim Ingham1391cc72012-09-22 00:04:04 +0000486 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000487 m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000488
Kate Stoneb9c1b512016-09-06 20:57:50 +0000489 m_bp_site_sp.reset();
490 return true;
491 }
492 return false;
493}
494
495void BreakpointLocation::GetDescription(Stream *s,
496 lldb::DescriptionLevel level) {
497 SymbolContext sc;
498
499 // If the description level is "initial" then the breakpoint is printing out
Adrian Prantl05097242018-04-30 16:49:04 +0000500 // our initial state, and we should let it decide how it wants to print our
501 // label.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000502 if (level != eDescriptionLevelInitial) {
503 s->Indent();
504 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
505 }
506
507 if (level == lldb::eDescriptionLevelBrief)
508 return;
509
510 if (level != eDescriptionLevelInitial)
511 s->PutCString(": ");
512
513 if (level == lldb::eDescriptionLevelVerbose)
514 s->IndentMore();
515
516 if (m_address.IsSectionOffset()) {
517 m_address.CalculateSymbolContext(&sc);
518
519 if (level == lldb::eDescriptionLevelFull ||
520 level == eDescriptionLevelInitial) {
521 if (IsReExported())
522 s->PutCString("re-exported target = ");
523 else
524 s->PutCString("where = ");
525 sc.DumpStopContext(s, m_owner.GetTarget().GetProcessSP().get(), m_address,
526 false, true, false, true, true);
527 } else {
528 if (sc.module_sp) {
529 s->EOL();
530 s->Indent("module = ");
531 sc.module_sp->GetFileSpec().Dump(s);
532 }
533
534 if (sc.comp_unit != nullptr) {
535 s->EOL();
536 s->Indent("compile unit = ");
537 static_cast<FileSpec *>(sc.comp_unit)->GetFilename().Dump(s);
538
539 if (sc.function != nullptr) {
540 s->EOL();
541 s->Indent("function = ");
542 s->PutCString(sc.function->GetName().AsCString("<unknown>"));
543 }
544
545 if (sc.line_entry.line > 0) {
546 s->EOL();
547 s->Indent("location = ");
548 sc.line_entry.DumpStopContext(s, true);
549 }
550
551 } else {
552 // If we don't have a comp unit, see if we have a symbol we can print.
553 if (sc.symbol) {
554 s->EOL();
555 if (IsReExported())
556 s->Indent("re-exported target = ");
557 else
558 s->Indent("symbol = ");
559 s->PutCString(sc.symbol->GetName().AsCString("<unknown>"));
560 }
561 }
562 }
563 }
564
565 if (level == lldb::eDescriptionLevelVerbose) {
566 s->EOL();
567 s->Indent();
568 }
569
570 if (m_address.IsSectionOffset() &&
571 (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
572 s->Printf(", ");
573 s->Printf("address = ");
574
575 ExecutionContextScope *exe_scope = nullptr;
576 Target *target = &m_owner.GetTarget();
577 if (target)
578 exe_scope = target->GetProcessSP().get();
579 if (exe_scope == nullptr)
580 exe_scope = target;
581
582 if (level == eDescriptionLevelInitial)
583 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
584 Address::DumpStyleFileAddress);
585 else
586 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
587 Address::DumpStyleModuleWithFileAddress);
588
589 if (IsIndirect() && m_bp_site_sp) {
590 Address resolved_address;
591 resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
592 Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
593 if (resolved_symbol) {
594 if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
595 s->Printf(", ");
596 else if (level == lldb::eDescriptionLevelVerbose) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000597 s->EOL();
598 s->Indent();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000599 }
600 s->Printf("indirect target = %s",
601 resolved_symbol->GetName().GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000602 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000603 }
604
605 if (level == lldb::eDescriptionLevelVerbose) {
606 s->EOL();
607 s->Indent();
608 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
609
610 s->Indent();
611 s->Printf("hit count = %-4u\n", GetHitCount());
612
613 if (m_options_ap.get()) {
614 s->Indent();
615 m_options_ap->GetDescription(s, level);
616 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000617 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000618 s->IndentLess();
619 } else if (level != eDescriptionLevelInitial) {
620 s->Printf(", %sresolved, hit count = %u ", (IsResolved() ? "" : "un"),
621 GetHitCount());
622 if (m_options_ap.get()) {
623 m_options_ap->GetDescription(s, level);
624 }
625 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000626}
627
Kate Stoneb9c1b512016-09-06 20:57:50 +0000628void BreakpointLocation::Dump(Stream *s) const {
629 if (s == nullptr)
630 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000631
Jim Inghamaf26b222017-08-02 00:16:10 +0000632 lldb::tid_t tid = GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
633 ->GetThreadSpecNoCreate()->GetTID();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000634 s->Printf(
635 "BreakpointLocation %u: tid = %4.4" PRIx64 " load addr = 0x%8.8" PRIx64
636 " state = %s type = %s breakpoint "
637 "hw_index = %i hit_count = %-4u ignore_count = %-4u",
Jim Inghamaf26b222017-08-02 00:16:10 +0000638 GetID(), tid,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000639 (uint64_t)m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()),
640 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled())
641 ? "enabled "
642 : "disabled",
643 IsHardware() ? "hardware" : "software", GetHardwareIndex(), GetHitCount(),
Jim Inghamaf26b222017-08-02 00:16:10 +0000644 GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
645 ->GetIgnoreCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000646}
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000647
Kate Stoneb9c1b512016-09-06 20:57:50 +0000648void BreakpointLocation::SendBreakpointLocationChangedEvent(
649 lldb::BreakpointEventType eventKind) {
650 if (!m_being_created && !m_owner.IsInternal() &&
651 m_owner.GetTarget().EventTypeHasListeners(
652 Target::eBroadcastBitBreakpointChanged)) {
653 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData(
654 eventKind, m_owner.shared_from_this());
655 data->GetBreakpointLocationCollection().Add(shared_from_this());
656 m_owner.GetTarget().BroadcastEvent(Target::eBroadcastBitBreakpointChanged,
657 data);
658 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000659}
Jim Ingham77fd7382014-09-10 21:40:47 +0000660
Kate Stoneb9c1b512016-09-06 20:57:50 +0000661void BreakpointLocation::SwapLocation(BreakpointLocationSP swap_from) {
662 m_address = swap_from->m_address;
663 m_should_resolve_indirect_functions =
664 swap_from->m_should_resolve_indirect_functions;
665 m_is_reexported = swap_from->m_is_reexported;
666 m_is_indirect = swap_from->m_is_indirect;
667 m_user_expression_sp.reset();
Jim Ingham77fd7382014-09-10 21:40:47 +0000668}