blob: 578267a412d851efe908434de8a80a1f6f984d07 [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"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include "lldb/Core/Log.h"
Greg Clayton1f746072012-08-29 21:13:06 +000019#include "lldb/Core/Module.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020#include "lldb/Core/StreamString.h"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000021#include "lldb/Core/ValueObject.h"
Sean Callanan579e70c2016-03-19 00:03:59 +000022#include "lldb/Expression/DiagnosticManager.h"
Bruce Mitchener937e3962015-09-21 16:56:08 +000023#include "lldb/Expression/ExpressionVariable.h"
Jim Ingham151c0322015-09-15 21:13:50 +000024#include "lldb/Expression/UserExpression.h"
Greg Clayton1f746072012-08-29 21:13:06 +000025#include "lldb/Symbol/CompileUnit.h"
26#include "lldb/Symbol/Symbol.h"
Jim Ingham151c0322015-09-15 21:13:50 +000027#include "lldb/Symbol/TypeSystem.h"
Greg Clayton1f746072012-08-29 21:13:06 +000028#include "lldb/Target/Process.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000029#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "lldb/Target/Thread.h"
Jim Ingham1b54c882010-06-16 02:00:15 +000031#include "lldb/Target/ThreadSpec.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
Kate Stoneb9c1b512016-09-06 20:57:50 +000061Address &BreakpointLocation::GetAddress() { return m_address; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000062
Kate Stoneb9c1b512016-09-06 20:57:50 +000063Breakpoint &BreakpointLocation::GetBreakpoint() { return m_owner; }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000064
Kate Stoneb9c1b512016-09-06 20:57:50 +000065Target &BreakpointLocation::GetTarget() { return m_owner.GetTarget(); }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066
Kate Stoneb9c1b512016-09-06 20:57:50 +000067bool BreakpointLocation::IsEnabled() const {
68 if (!m_owner.IsEnabled())
69 return false;
70 else if (m_options_ap.get() != nullptr)
71 return m_options_ap->IsEnabled();
72 else
Jim Ingham0fd1b752012-06-26 22:27:55 +000073 return true;
74}
75
Kate Stoneb9c1b512016-09-06 20:57:50 +000076void BreakpointLocation::SetEnabled(bool enabled) {
77 GetLocationOptions()->SetEnabled(enabled);
78 if (enabled) {
79 ResolveBreakpointSite();
80 } else {
81 ClearBreakpointSite();
82 }
83 SendBreakpointLocationChangedEvent(enabled ? eBreakpointEventTypeEnabled
84 : eBreakpointEventTypeDisabled);
85}
86
87void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) {
88 if (thread_id != LLDB_INVALID_THREAD_ID)
89 GetLocationOptions()->SetThreadID(thread_id);
90 else {
91 // If we're resetting this to an invalid thread id, then
92 // don't make an options pointer just to do that.
Eugene Zelenko16fd7512015-10-30 18:50:12 +000093 if (m_options_ap.get() != nullptr)
Kate Stoneb9c1b512016-09-06 20:57:50 +000094 m_options_ap->SetThreadID(thread_id);
95 }
96 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000097}
98
Kate Stoneb9c1b512016-09-06 20:57:50 +000099lldb::tid_t BreakpointLocation::GetThreadID() {
100 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
101 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
102 else
103 return LLDB_INVALID_THREAD_ID;
104}
105
106void BreakpointLocation::SetThreadIndex(uint32_t index) {
107 if (index != 0)
108 GetLocationOptions()->GetThreadSpec()->SetIndex(index);
109 else {
110 // If we're resetting this to an invalid thread id, then
111 // don't make an options pointer just to do that.
112 if (m_options_ap.get() != nullptr)
113 m_options_ap->GetThreadSpec()->SetIndex(index);
114 }
115 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
116}
117
118uint32_t BreakpointLocation::GetThreadIndex() const {
119 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
120 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
121 else
122 return 0;
123}
124
125void BreakpointLocation::SetThreadName(const char *thread_name) {
126 if (thread_name != nullptr)
127 GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
128 else {
129 // If we're resetting this to an invalid thread id, then
130 // don't make an options pointer just to do that.
131 if (m_options_ap.get() != nullptr)
132 m_options_ap->GetThreadSpec()->SetName(thread_name);
133 }
134 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
135}
136
137const char *BreakpointLocation::GetThreadName() const {
138 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
139 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
140 else
141 return nullptr;
142}
143
144void BreakpointLocation::SetQueueName(const char *queue_name) {
145 if (queue_name != nullptr)
146 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
147 else {
148 // If we're resetting this to an invalid thread id, then
149 // don't make an options pointer just to do that.
150 if (m_options_ap.get() != nullptr)
151 m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
152 }
153 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
154}
155
156const char *BreakpointLocation::GetQueueName() const {
157 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
158 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
159 else
160 return nullptr;
161}
162
163bool BreakpointLocation::InvokeCallback(StoppointCallbackContext *context) {
164 if (m_options_ap.get() != nullptr && m_options_ap->HasCallback())
165 return m_options_ap->InvokeCallback(context, m_owner.GetID(), GetID());
166 else
167 return m_owner.InvokeCallback(context, GetID());
168}
169
170void BreakpointLocation::SetCallback(BreakpointHitCallback callback,
171 void *baton, bool is_synchronous) {
172 // The default "Baton" class will keep a copy of "baton" and won't free
173 // or delete it when it goes goes out of scope.
Zachary Turner4e4fbe82016-09-13 17:53:38 +0000174 GetLocationOptions()->SetCallback(
175 callback, std::make_shared<UntypedBaton>(baton), is_synchronous);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000176 SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);
177}
178
179void BreakpointLocation::SetCallback(BreakpointHitCallback callback,
180 const BatonSP &baton_sp,
181 bool is_synchronous) {
182 GetLocationOptions()->SetCallback(callback, baton_sp, is_synchronous);
183 SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);
184}
185
186void BreakpointLocation::ClearCallback() {
187 GetLocationOptions()->ClearCallback();
188}
189
190void BreakpointLocation::SetCondition(const char *condition) {
191 GetLocationOptions()->SetCondition(condition);
192 SendBreakpointLocationChangedEvent(eBreakpointEventTypeConditionChanged);
193}
194
195const char *BreakpointLocation::GetConditionText(size_t *hash) const {
196 return GetOptionsNoCreate()->GetConditionText(hash);
197}
198
199bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,
200 Error &error) {
201 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
202
203 std::lock_guard<std::mutex> guard(m_condition_mutex);
204
205 size_t condition_hash;
206 const char *condition_text = GetConditionText(&condition_hash);
207
208 if (!condition_text) {
209 m_user_expression_sp.reset();
210 return false;
211 }
212
213 error.Clear();
214
215 DiagnosticManager diagnostics;
216
217 if (condition_hash != m_condition_hash || !m_user_expression_sp ||
218 !m_user_expression_sp->MatchesContext(exe_ctx)) {
219 LanguageType language = eLanguageTypeUnknown;
220 // See if we can figure out the language from the frame, otherwise use the
221 // default language:
222 CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit();
223 if (comp_unit)
224 language = comp_unit->GetLanguage();
225
226 m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(
Zachary Turnerc5d7df92016-11-08 04:52:16 +0000227 condition_text, llvm::StringRef(), language, Expression::eResultTypeAny,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000228 EvaluateExpressionOptions(), error));
229 if (error.Fail()) {
230 if (log)
231 log->Printf("Error getting condition expression: %s.",
232 error.AsCString());
233 m_user_expression_sp.reset();
234 return true;
235 }
236
237 if (!m_user_expression_sp->Parse(diagnostics, exe_ctx,
238 eExecutionPolicyOnlyWhenNeeded, true,
239 false)) {
240 error.SetErrorStringWithFormat(
241 "Couldn't parse conditional expression:\n%s",
242 diagnostics.GetString().c_str());
243 m_user_expression_sp.reset();
244 return true;
245 }
246
247 m_condition_hash = condition_hash;
248 }
249
250 // We need to make sure the user sees any parse errors in their condition, so
251 // we'll hook the
252 // constructor errors up to the debugger's Async I/O.
253
254 ValueObjectSP result_value_sp;
255
256 EvaluateExpressionOptions options;
257 options.SetUnwindOnError(true);
258 options.SetIgnoreBreakpoints(true);
259 options.SetTryAllThreads(true);
260 options.SetResultIsInternal(
261 true); // Don't generate a user variable for condition expressions.
262
263 Error expr_error;
264
265 diagnostics.Clear();
266
267 ExpressionVariableSP result_variable_sp;
268
269 ExpressionResults result_code = m_user_expression_sp->Execute(
270 diagnostics, exe_ctx, options, m_user_expression_sp, result_variable_sp);
271
272 bool ret;
273
274 if (result_code == eExpressionCompleted) {
275 if (!result_variable_sp) {
276 error.SetErrorString("Expression did not return a result");
277 return false;
278 }
279
280 result_value_sp = result_variable_sp->GetValueObject();
281
282 if (result_value_sp) {
283 ret = result_value_sp->IsLogicalTrue(error);
284 if (log) {
285 if (error.Success()) {
286 log->Printf("Condition successfully evaluated, result is %s.\n",
287 ret ? "true" : "false");
288 } else {
289 error.SetErrorString(
290 "Failed to get an integer result from the expression");
291 ret = false;
292 }
293 }
294 } else {
295 ret = false;
296 error.SetErrorString("Failed to get any result from the expression");
297 }
298 } else {
299 ret = false;
300 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s",
301 diagnostics.GetString().c_str());
302 }
303
304 return ret;
305}
306
307uint32_t BreakpointLocation::GetIgnoreCount() {
308 return GetOptionsNoCreate()->GetIgnoreCount();
309}
310
311void BreakpointLocation::SetIgnoreCount(uint32_t n) {
312 GetLocationOptions()->SetIgnoreCount(n);
313 SendBreakpointLocationChangedEvent(eBreakpointEventTypeIgnoreChanged);
314}
315
316void BreakpointLocation::DecrementIgnoreCount() {
317 if (m_options_ap.get() != nullptr) {
318 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
319 if (loc_ignore != 0)
320 m_options_ap->SetIgnoreCount(loc_ignore - 1);
321 }
322}
323
324bool BreakpointLocation::IgnoreCountShouldStop() {
325 if (m_options_ap.get() != nullptr) {
326 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
327 if (loc_ignore != 0) {
328 m_owner.DecrementIgnoreCount();
329 DecrementIgnoreCount(); // Have to decrement our owners' ignore count,
330 // since it won't get a
331 // chance to.
332 return false;
333 }
334 }
335 return true;
336}
337
338const BreakpointOptions *BreakpointLocation::GetOptionsNoCreate() const {
339 if (m_options_ap.get() != nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000340 return m_options_ap.get();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000341 else
342 return m_owner.GetOptions();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000343}
344
Kate Stoneb9c1b512016-09-06 20:57:50 +0000345BreakpointOptions *BreakpointLocation::GetLocationOptions() {
346 // If we make the copy we don't copy the callbacks because that is potentially
347 // expensive and we don't want to do that for the simple case where someone is
348 // just disabling the location.
349 if (m_options_ap.get() == nullptr)
350 m_options_ap.reset(
351 BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions()));
352
353 return m_options_ap.get();
354}
355
356bool BreakpointLocation::ValidForThisThread(Thread *thread) {
357 return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
Jim Ingham1b54c882010-06-16 02:00:15 +0000358}
359
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000360// RETURNS - true if we should stop at this breakpoint, false if we
Jim Ingham1b54c882010-06-16 02:00:15 +0000361// should continue. Note, we don't check the thread spec for the breakpoint
362// here, since if the breakpoint is not for this thread, then the event won't
363// even get reported, so the check is redundant.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000364
Kate Stoneb9c1b512016-09-06 20:57:50 +0000365bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) {
366 bool should_stop = true;
367 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000368
Kate Stoneb9c1b512016-09-06 20:57:50 +0000369 // Do this first, if a location is disabled, it shouldn't increment its hit
370 // count.
371 if (!IsEnabled())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000372 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000373
374 if (!IgnoreCountShouldStop())
375 return false;
376
377 if (!m_owner.IgnoreCountShouldStop())
378 return false;
379
380 // We only run synchronous callbacks in ShouldStop:
381 context->is_synchronous = true;
382 should_stop = InvokeCallback(context);
383
384 if (log) {
385 StreamString s;
386 GetDescription(&s, lldb::eDescriptionLevelVerbose);
387 log->Printf("Hit breakpoint location: %s, %s.\n", s.GetData(),
388 should_stop ? "stopping" : "continuing");
389 }
390
391 return should_stop;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000392}
393
Kate Stoneb9c1b512016-09-06 20:57:50 +0000394void BreakpointLocation::BumpHitCount() {
395 if (IsEnabled()) {
396 // Step our hit count, and also step the hit count of the owner.
397 IncrementHitCount();
398 m_owner.IncrementHitCount();
399 }
400}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000401
Kate Stoneb9c1b512016-09-06 20:57:50 +0000402void BreakpointLocation::UndoBumpHitCount() {
403 if (IsEnabled()) {
404 // Step our hit count, and also step the hit count of the owner.
405 DecrementHitCount();
406 m_owner.DecrementHitCount();
407 }
408}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000409
Kate Stoneb9c1b512016-09-06 20:57:50 +0000410bool BreakpointLocation::IsResolved() const {
411 return m_bp_site_sp.get() != nullptr;
412}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000413
Kate Stoneb9c1b512016-09-06 20:57:50 +0000414lldb::BreakpointSiteSP BreakpointLocation::GetBreakpointSite() const {
415 return m_bp_site_sp;
416}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000417
Kate Stoneb9c1b512016-09-06 20:57:50 +0000418bool BreakpointLocation::ResolveBreakpointSite() {
419 if (m_bp_site_sp)
420 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000421
Kate Stoneb9c1b512016-09-06 20:57:50 +0000422 Process *process = m_owner.GetTarget().GetProcessSP().get();
423 if (process == nullptr)
424 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000425
Kate Stoneb9c1b512016-09-06 20:57:50 +0000426 lldb::break_id_t new_id =
427 process->CreateBreakpointSite(shared_from_this(), m_owner.IsHardware());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000428
Kate Stoneb9c1b512016-09-06 20:57:50 +0000429 if (new_id == LLDB_INVALID_BREAK_ID) {
430 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
431 if (log)
432 log->Warning("Tried to add breakpoint site at 0x%" PRIx64
433 " but it was already present.\n",
434 m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()));
435 return false;
436 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000437
Kate Stoneb9c1b512016-09-06 20:57:50 +0000438 return true;
439}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000440
Kate Stoneb9c1b512016-09-06 20:57:50 +0000441bool BreakpointLocation::SetBreakpointSite(BreakpointSiteSP &bp_site_sp) {
442 m_bp_site_sp = bp_site_sp;
443 SendBreakpointLocationChangedEvent(eBreakpointEventTypeLocationsResolved);
444 return true;
445}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000446
Kate Stoneb9c1b512016-09-06 20:57:50 +0000447bool BreakpointLocation::ClearBreakpointSite() {
448 if (m_bp_site_sp.get()) {
449 ProcessSP process_sp(m_owner.GetTarget().GetProcessSP());
450 // If the process exists, get it to remove the owner, it will remove the
451 // physical implementation
452 // of the breakpoint as well if there are no more owners. Otherwise just
453 // remove this owner.
454 if (process_sp)
455 process_sp->RemoveOwnerFromBreakpointSite(GetBreakpoint().GetID(),
456 GetID(), m_bp_site_sp);
Jim Ingham1391cc72012-09-22 00:04:04 +0000457 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000458 m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000459
Kate Stoneb9c1b512016-09-06 20:57:50 +0000460 m_bp_site_sp.reset();
461 return true;
462 }
463 return false;
464}
465
466void BreakpointLocation::GetDescription(Stream *s,
467 lldb::DescriptionLevel level) {
468 SymbolContext sc;
469
470 // If the description level is "initial" then the breakpoint is printing out
471 // our initial state,
472 // and we should let it decide how it wants to print our label.
473 if (level != eDescriptionLevelInitial) {
474 s->Indent();
475 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
476 }
477
478 if (level == lldb::eDescriptionLevelBrief)
479 return;
480
481 if (level != eDescriptionLevelInitial)
482 s->PutCString(": ");
483
484 if (level == lldb::eDescriptionLevelVerbose)
485 s->IndentMore();
486
487 if (m_address.IsSectionOffset()) {
488 m_address.CalculateSymbolContext(&sc);
489
490 if (level == lldb::eDescriptionLevelFull ||
491 level == eDescriptionLevelInitial) {
492 if (IsReExported())
493 s->PutCString("re-exported target = ");
494 else
495 s->PutCString("where = ");
496 sc.DumpStopContext(s, m_owner.GetTarget().GetProcessSP().get(), m_address,
497 false, true, false, true, true);
498 } else {
499 if (sc.module_sp) {
500 s->EOL();
501 s->Indent("module = ");
502 sc.module_sp->GetFileSpec().Dump(s);
503 }
504
505 if (sc.comp_unit != nullptr) {
506 s->EOL();
507 s->Indent("compile unit = ");
508 static_cast<FileSpec *>(sc.comp_unit)->GetFilename().Dump(s);
509
510 if (sc.function != nullptr) {
511 s->EOL();
512 s->Indent("function = ");
513 s->PutCString(sc.function->GetName().AsCString("<unknown>"));
514 }
515
516 if (sc.line_entry.line > 0) {
517 s->EOL();
518 s->Indent("location = ");
519 sc.line_entry.DumpStopContext(s, true);
520 }
521
522 } else {
523 // If we don't have a comp unit, see if we have a symbol we can print.
524 if (sc.symbol) {
525 s->EOL();
526 if (IsReExported())
527 s->Indent("re-exported target = ");
528 else
529 s->Indent("symbol = ");
530 s->PutCString(sc.symbol->GetName().AsCString("<unknown>"));
531 }
532 }
533 }
534 }
535
536 if (level == lldb::eDescriptionLevelVerbose) {
537 s->EOL();
538 s->Indent();
539 }
540
541 if (m_address.IsSectionOffset() &&
542 (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
543 s->Printf(", ");
544 s->Printf("address = ");
545
546 ExecutionContextScope *exe_scope = nullptr;
547 Target *target = &m_owner.GetTarget();
548 if (target)
549 exe_scope = target->GetProcessSP().get();
550 if (exe_scope == nullptr)
551 exe_scope = target;
552
553 if (level == eDescriptionLevelInitial)
554 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
555 Address::DumpStyleFileAddress);
556 else
557 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
558 Address::DumpStyleModuleWithFileAddress);
559
560 if (IsIndirect() && m_bp_site_sp) {
561 Address resolved_address;
562 resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
563 Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
564 if (resolved_symbol) {
565 if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
566 s->Printf(", ");
567 else if (level == lldb::eDescriptionLevelVerbose) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000568 s->EOL();
569 s->Indent();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000570 }
571 s->Printf("indirect target = %s",
572 resolved_symbol->GetName().GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000573 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000574 }
575
576 if (level == lldb::eDescriptionLevelVerbose) {
577 s->EOL();
578 s->Indent();
579 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
580
581 s->Indent();
582 s->Printf("hit count = %-4u\n", GetHitCount());
583
584 if (m_options_ap.get()) {
585 s->Indent();
586 m_options_ap->GetDescription(s, level);
587 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000588 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000589 s->IndentLess();
590 } else if (level != eDescriptionLevelInitial) {
591 s->Printf(", %sresolved, hit count = %u ", (IsResolved() ? "" : "un"),
592 GetHitCount());
593 if (m_options_ap.get()) {
594 m_options_ap->GetDescription(s, level);
595 }
596 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000597}
598
Kate Stoneb9c1b512016-09-06 20:57:50 +0000599void BreakpointLocation::Dump(Stream *s) const {
600 if (s == nullptr)
601 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000602
Kate Stoneb9c1b512016-09-06 20:57:50 +0000603 s->Printf(
604 "BreakpointLocation %u: tid = %4.4" PRIx64 " load addr = 0x%8.8" PRIx64
605 " state = %s type = %s breakpoint "
606 "hw_index = %i hit_count = %-4u ignore_count = %-4u",
607 GetID(), GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
608 (uint64_t)m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()),
609 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled())
610 ? "enabled "
611 : "disabled",
612 IsHardware() ? "hardware" : "software", GetHardwareIndex(), GetHitCount(),
613 GetOptionsNoCreate()->GetIgnoreCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000614}
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000615
Kate Stoneb9c1b512016-09-06 20:57:50 +0000616void BreakpointLocation::SendBreakpointLocationChangedEvent(
617 lldb::BreakpointEventType eventKind) {
618 if (!m_being_created && !m_owner.IsInternal() &&
619 m_owner.GetTarget().EventTypeHasListeners(
620 Target::eBroadcastBitBreakpointChanged)) {
621 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData(
622 eventKind, m_owner.shared_from_this());
623 data->GetBreakpointLocationCollection().Add(shared_from_this());
624 m_owner.GetTarget().BroadcastEvent(Target::eBroadcastBitBreakpointChanged,
625 data);
626 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000627}
Jim Ingham77fd7382014-09-10 21:40:47 +0000628
Kate Stoneb9c1b512016-09-06 20:57:50 +0000629void BreakpointLocation::SwapLocation(BreakpointLocationSP swap_from) {
630 m_address = swap_from->m_address;
631 m_should_resolve_indirect_functions =
632 swap_from->m_should_resolve_indirect_functions;
633 m_is_reexported = swap_from->m_is_reexported;
634 m_is_indirect = swap_from->m_is_indirect;
635 m_user_expression_sp.reset();
Jim Ingham77fd7382014-09-10 21:40:47 +0000636}