blob: 15865be3f9a08261cf93b8ef04728c91ce34489b [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
96void BreakpointLocation::SetThreadID(lldb::tid_t thread_id) {
97 if (thread_id != LLDB_INVALID_THREAD_ID)
98 GetLocationOptions()->SetThreadID(thread_id);
99 else {
100 // If we're resetting this to an invalid thread id, then
101 // don't make an options pointer just to do that.
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000102 if (m_options_ap.get() != nullptr)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000103 m_options_ap->SetThreadID(thread_id);
104 }
105 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000106}
107
Kate Stoneb9c1b512016-09-06 20:57:50 +0000108lldb::tid_t BreakpointLocation::GetThreadID() {
Jim Inghamaf26b222017-08-02 00:16:10 +0000109 const ThreadSpec *thread_spec =
110 GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
111 ->GetThreadSpecNoCreate();
112 if (thread_spec)
113 return thread_spec->GetTID();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114 else
115 return LLDB_INVALID_THREAD_ID;
116}
117
118void BreakpointLocation::SetThreadIndex(uint32_t index) {
119 if (index != 0)
120 GetLocationOptions()->GetThreadSpec()->SetIndex(index);
121 else {
122 // If we're resetting this to an invalid thread id, then
123 // don't make an options pointer just to do that.
124 if (m_options_ap.get() != nullptr)
125 m_options_ap->GetThreadSpec()->SetIndex(index);
126 }
127 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
128}
129
130uint32_t BreakpointLocation::GetThreadIndex() const {
Jim Inghamaf26b222017-08-02 00:16:10 +0000131 const ThreadSpec *thread_spec =
132 GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
133 ->GetThreadSpecNoCreate();
134 if (thread_spec)
135 return thread_spec->GetIndex();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000136 else
137 return 0;
138}
139
140void BreakpointLocation::SetThreadName(const char *thread_name) {
141 if (thread_name != nullptr)
142 GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
143 else {
144 // If we're resetting this to an invalid thread id, then
145 // don't make an options pointer just to do that.
146 if (m_options_ap.get() != nullptr)
147 m_options_ap->GetThreadSpec()->SetName(thread_name);
148 }
149 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
150}
151
152const char *BreakpointLocation::GetThreadName() const {
Jim Inghamaf26b222017-08-02 00:16:10 +0000153 const ThreadSpec *thread_spec =
154 GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
155 ->GetThreadSpecNoCreate();
156 if (thread_spec)
157 return thread_spec->GetName();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000158 else
159 return nullptr;
160}
161
162void BreakpointLocation::SetQueueName(const char *queue_name) {
163 if (queue_name != nullptr)
164 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
165 else {
166 // If we're resetting this to an invalid thread id, then
167 // don't make an options pointer just to do that.
168 if (m_options_ap.get() != nullptr)
169 m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
170 }
171 SendBreakpointLocationChangedEvent(eBreakpointEventTypeThreadChanged);
172}
173
174const char *BreakpointLocation::GetQueueName() const {
Jim Inghamaf26b222017-08-02 00:16:10 +0000175 const ThreadSpec *thread_spec =
176 GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
177 ->GetThreadSpecNoCreate();
178 if (thread_spec)
179 return thread_spec->GetQueueName();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000180 else
181 return nullptr;
182}
183
184bool BreakpointLocation::InvokeCallback(StoppointCallbackContext *context) {
185 if (m_options_ap.get() != nullptr && m_options_ap->HasCallback())
186 return m_options_ap->InvokeCallback(context, m_owner.GetID(), GetID());
187 else
188 return m_owner.InvokeCallback(context, GetID());
189}
190
191void BreakpointLocation::SetCallback(BreakpointHitCallback callback,
192 void *baton, bool is_synchronous) {
193 // The default "Baton" class will keep a copy of "baton" and won't free
194 // or delete it when it goes goes out of scope.
Zachary Turner4e4fbe82016-09-13 17:53:38 +0000195 GetLocationOptions()->SetCallback(
196 callback, std::make_shared<UntypedBaton>(baton), is_synchronous);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000197 SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);
198}
199
200void BreakpointLocation::SetCallback(BreakpointHitCallback callback,
201 const BatonSP &baton_sp,
202 bool is_synchronous) {
203 GetLocationOptions()->SetCallback(callback, baton_sp, is_synchronous);
204 SendBreakpointLocationChangedEvent(eBreakpointEventTypeCommandChanged);
205}
206
207void BreakpointLocation::ClearCallback() {
208 GetLocationOptions()->ClearCallback();
209}
210
211void BreakpointLocation::SetCondition(const char *condition) {
212 GetLocationOptions()->SetCondition(condition);
213 SendBreakpointLocationChangedEvent(eBreakpointEventTypeConditionChanged);
214}
215
216const char *BreakpointLocation::GetConditionText(size_t *hash) const {
Jim Inghamaf26b222017-08-02 00:16:10 +0000217 return GetOptionsSpecifyingKind(BreakpointOptions::eCondition)
218 ->GetConditionText(hash);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000219}
220
221bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx,
Zachary Turner97206d52017-05-12 04:51:55 +0000222 Status &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000223 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
224
225 std::lock_guard<std::mutex> guard(m_condition_mutex);
226
227 size_t condition_hash;
228 const char *condition_text = GetConditionText(&condition_hash);
229
230 if (!condition_text) {
231 m_user_expression_sp.reset();
232 return false;
233 }
234
235 error.Clear();
236
237 DiagnosticManager diagnostics;
238
239 if (condition_hash != m_condition_hash || !m_user_expression_sp ||
240 !m_user_expression_sp->MatchesContext(exe_ctx)) {
241 LanguageType language = eLanguageTypeUnknown;
242 // See if we can figure out the language from the frame, otherwise use the
243 // default language:
244 CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit();
245 if (comp_unit)
246 language = comp_unit->GetLanguage();
247
248 m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(
Zachary Turnerc5d7df92016-11-08 04:52:16 +0000249 condition_text, llvm::StringRef(), language, Expression::eResultTypeAny,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000250 EvaluateExpressionOptions(), error));
251 if (error.Fail()) {
252 if (log)
253 log->Printf("Error getting condition expression: %s.",
254 error.AsCString());
255 m_user_expression_sp.reset();
256 return true;
257 }
258
259 if (!m_user_expression_sp->Parse(diagnostics, exe_ctx,
260 eExecutionPolicyOnlyWhenNeeded, true,
261 false)) {
262 error.SetErrorStringWithFormat(
263 "Couldn't parse conditional expression:\n%s",
264 diagnostics.GetString().c_str());
265 m_user_expression_sp.reset();
266 return true;
267 }
268
269 m_condition_hash = condition_hash;
270 }
271
272 // We need to make sure the user sees any parse errors in their condition, so
273 // we'll hook the
274 // constructor errors up to the debugger's Async I/O.
275
276 ValueObjectSP result_value_sp;
277
278 EvaluateExpressionOptions options;
279 options.SetUnwindOnError(true);
280 options.SetIgnoreBreakpoints(true);
281 options.SetTryAllThreads(true);
282 options.SetResultIsInternal(
283 true); // Don't generate a user variable for condition expressions.
284
Zachary Turner97206d52017-05-12 04:51:55 +0000285 Status expr_error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000286
287 diagnostics.Clear();
288
289 ExpressionVariableSP result_variable_sp;
290
291 ExpressionResults result_code = m_user_expression_sp->Execute(
292 diagnostics, exe_ctx, options, m_user_expression_sp, result_variable_sp);
293
294 bool ret;
295
296 if (result_code == eExpressionCompleted) {
297 if (!result_variable_sp) {
298 error.SetErrorString("Expression did not return a result");
299 return false;
300 }
301
302 result_value_sp = result_variable_sp->GetValueObject();
303
304 if (result_value_sp) {
305 ret = result_value_sp->IsLogicalTrue(error);
306 if (log) {
307 if (error.Success()) {
308 log->Printf("Condition successfully evaluated, result is %s.\n",
309 ret ? "true" : "false");
310 } else {
311 error.SetErrorString(
312 "Failed to get an integer result from the expression");
313 ret = false;
314 }
315 }
316 } else {
317 ret = false;
318 error.SetErrorString("Failed to get any result from the expression");
319 }
320 } else {
321 ret = false;
322 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s",
323 diagnostics.GetString().c_str());
324 }
325
326 return ret;
327}
328
329uint32_t BreakpointLocation::GetIgnoreCount() {
Jim Inghamaf26b222017-08-02 00:16:10 +0000330 return GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
331 ->GetIgnoreCount();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000332}
333
334void BreakpointLocation::SetIgnoreCount(uint32_t n) {
335 GetLocationOptions()->SetIgnoreCount(n);
336 SendBreakpointLocationChangedEvent(eBreakpointEventTypeIgnoreChanged);
337}
338
339void BreakpointLocation::DecrementIgnoreCount() {
340 if (m_options_ap.get() != nullptr) {
341 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
342 if (loc_ignore != 0)
343 m_options_ap->SetIgnoreCount(loc_ignore - 1);
344 }
345}
346
347bool BreakpointLocation::IgnoreCountShouldStop() {
348 if (m_options_ap.get() != nullptr) {
349 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
350 if (loc_ignore != 0) {
351 m_owner.DecrementIgnoreCount();
352 DecrementIgnoreCount(); // Have to decrement our owners' ignore count,
353 // since it won't get a
354 // chance to.
355 return false;
356 }
357 }
358 return true;
359}
360
Kate Stoneb9c1b512016-09-06 20:57:50 +0000361BreakpointOptions *BreakpointLocation::GetLocationOptions() {
362 // If we make the copy we don't copy the callbacks because that is potentially
363 // expensive and we don't want to do that for the simple case where someone is
364 // just disabling the location.
365 if (m_options_ap.get() == nullptr)
366 m_options_ap.reset(
Jim Inghamaf26b222017-08-02 00:16:10 +0000367 new BreakpointOptions(false));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000368
369 return m_options_ap.get();
370}
371
372bool BreakpointLocation::ValidForThisThread(Thread *thread) {
Jim Inghamaf26b222017-08-02 00:16:10 +0000373 return thread
374 ->MatchesSpec(GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
375 ->GetThreadSpecNoCreate());
Jim Ingham1b54c882010-06-16 02:00:15 +0000376}
377
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000378// RETURNS - true if we should stop at this breakpoint, false if we
Jim Ingham1b54c882010-06-16 02:00:15 +0000379// should continue. Note, we don't check the thread spec for the breakpoint
380// here, since if the breakpoint is not for this thread, then the event won't
381// even get reported, so the check is redundant.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000382
Kate Stoneb9c1b512016-09-06 20:57:50 +0000383bool BreakpointLocation::ShouldStop(StoppointCallbackContext *context) {
384 bool should_stop = true;
385 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000386
Kate Stoneb9c1b512016-09-06 20:57:50 +0000387 // Do this first, if a location is disabled, it shouldn't increment its hit
388 // count.
389 if (!IsEnabled())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000390 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000391
392 if (!IgnoreCountShouldStop())
393 return false;
394
395 if (!m_owner.IgnoreCountShouldStop())
396 return false;
397
398 // We only run synchronous callbacks in ShouldStop:
399 context->is_synchronous = true;
400 should_stop = InvokeCallback(context);
401
402 if (log) {
403 StreamString s;
404 GetDescription(&s, lldb::eDescriptionLevelVerbose);
405 log->Printf("Hit breakpoint location: %s, %s.\n", s.GetData(),
406 should_stop ? "stopping" : "continuing");
407 }
408
409 return should_stop;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000410}
411
Kate Stoneb9c1b512016-09-06 20:57:50 +0000412void BreakpointLocation::BumpHitCount() {
413 if (IsEnabled()) {
414 // Step our hit count, and also step the hit count of the owner.
415 IncrementHitCount();
416 m_owner.IncrementHitCount();
417 }
418}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000419
Kate Stoneb9c1b512016-09-06 20:57:50 +0000420void BreakpointLocation::UndoBumpHitCount() {
421 if (IsEnabled()) {
422 // Step our hit count, and also step the hit count of the owner.
423 DecrementHitCount();
424 m_owner.DecrementHitCount();
425 }
426}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000427
Kate Stoneb9c1b512016-09-06 20:57:50 +0000428bool BreakpointLocation::IsResolved() const {
429 return m_bp_site_sp.get() != nullptr;
430}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000431
Kate Stoneb9c1b512016-09-06 20:57:50 +0000432lldb::BreakpointSiteSP BreakpointLocation::GetBreakpointSite() const {
433 return m_bp_site_sp;
434}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435
Kate Stoneb9c1b512016-09-06 20:57:50 +0000436bool BreakpointLocation::ResolveBreakpointSite() {
437 if (m_bp_site_sp)
438 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000439
Kate Stoneb9c1b512016-09-06 20:57:50 +0000440 Process *process = m_owner.GetTarget().GetProcessSP().get();
441 if (process == nullptr)
442 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000443
Kate Stoneb9c1b512016-09-06 20:57:50 +0000444 lldb::break_id_t new_id =
445 process->CreateBreakpointSite(shared_from_this(), m_owner.IsHardware());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000446
Kate Stoneb9c1b512016-09-06 20:57:50 +0000447 if (new_id == LLDB_INVALID_BREAK_ID) {
448 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS);
449 if (log)
450 log->Warning("Tried to add breakpoint site at 0x%" PRIx64
451 " but it was already present.\n",
452 m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()));
453 return false;
454 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000455
Kate Stoneb9c1b512016-09-06 20:57:50 +0000456 return true;
457}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000458
Kate Stoneb9c1b512016-09-06 20:57:50 +0000459bool BreakpointLocation::SetBreakpointSite(BreakpointSiteSP &bp_site_sp) {
460 m_bp_site_sp = bp_site_sp;
461 SendBreakpointLocationChangedEvent(eBreakpointEventTypeLocationsResolved);
462 return true;
463}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000464
Kate Stoneb9c1b512016-09-06 20:57:50 +0000465bool BreakpointLocation::ClearBreakpointSite() {
466 if (m_bp_site_sp.get()) {
467 ProcessSP process_sp(m_owner.GetTarget().GetProcessSP());
468 // If the process exists, get it to remove the owner, it will remove the
469 // physical implementation
470 // of the breakpoint as well if there are no more owners. Otherwise just
471 // remove this owner.
472 if (process_sp)
473 process_sp->RemoveOwnerFromBreakpointSite(GetBreakpoint().GetID(),
474 GetID(), m_bp_site_sp);
Jim Ingham1391cc72012-09-22 00:04:04 +0000475 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000476 m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000477
Kate Stoneb9c1b512016-09-06 20:57:50 +0000478 m_bp_site_sp.reset();
479 return true;
480 }
481 return false;
482}
483
484void BreakpointLocation::GetDescription(Stream *s,
485 lldb::DescriptionLevel level) {
486 SymbolContext sc;
487
488 // If the description level is "initial" then the breakpoint is printing out
489 // our initial state,
490 // and we should let it decide how it wants to print our label.
491 if (level != eDescriptionLevelInitial) {
492 s->Indent();
493 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
494 }
495
496 if (level == lldb::eDescriptionLevelBrief)
497 return;
498
499 if (level != eDescriptionLevelInitial)
500 s->PutCString(": ");
501
502 if (level == lldb::eDescriptionLevelVerbose)
503 s->IndentMore();
504
505 if (m_address.IsSectionOffset()) {
506 m_address.CalculateSymbolContext(&sc);
507
508 if (level == lldb::eDescriptionLevelFull ||
509 level == eDescriptionLevelInitial) {
510 if (IsReExported())
511 s->PutCString("re-exported target = ");
512 else
513 s->PutCString("where = ");
514 sc.DumpStopContext(s, m_owner.GetTarget().GetProcessSP().get(), m_address,
515 false, true, false, true, true);
516 } else {
517 if (sc.module_sp) {
518 s->EOL();
519 s->Indent("module = ");
520 sc.module_sp->GetFileSpec().Dump(s);
521 }
522
523 if (sc.comp_unit != nullptr) {
524 s->EOL();
525 s->Indent("compile unit = ");
526 static_cast<FileSpec *>(sc.comp_unit)->GetFilename().Dump(s);
527
528 if (sc.function != nullptr) {
529 s->EOL();
530 s->Indent("function = ");
531 s->PutCString(sc.function->GetName().AsCString("<unknown>"));
532 }
533
534 if (sc.line_entry.line > 0) {
535 s->EOL();
536 s->Indent("location = ");
537 sc.line_entry.DumpStopContext(s, true);
538 }
539
540 } else {
541 // If we don't have a comp unit, see if we have a symbol we can print.
542 if (sc.symbol) {
543 s->EOL();
544 if (IsReExported())
545 s->Indent("re-exported target = ");
546 else
547 s->Indent("symbol = ");
548 s->PutCString(sc.symbol->GetName().AsCString("<unknown>"));
549 }
550 }
551 }
552 }
553
554 if (level == lldb::eDescriptionLevelVerbose) {
555 s->EOL();
556 s->Indent();
557 }
558
559 if (m_address.IsSectionOffset() &&
560 (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
561 s->Printf(", ");
562 s->Printf("address = ");
563
564 ExecutionContextScope *exe_scope = nullptr;
565 Target *target = &m_owner.GetTarget();
566 if (target)
567 exe_scope = target->GetProcessSP().get();
568 if (exe_scope == nullptr)
569 exe_scope = target;
570
571 if (level == eDescriptionLevelInitial)
572 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
573 Address::DumpStyleFileAddress);
574 else
575 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress,
576 Address::DumpStyleModuleWithFileAddress);
577
578 if (IsIndirect() && m_bp_site_sp) {
579 Address resolved_address;
580 resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
581 Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
582 if (resolved_symbol) {
583 if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
584 s->Printf(", ");
585 else if (level == lldb::eDescriptionLevelVerbose) {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000586 s->EOL();
587 s->Indent();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000588 }
589 s->Printf("indirect target = %s",
590 resolved_symbol->GetName().GetCString());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000591 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000592 }
593
594 if (level == lldb::eDescriptionLevelVerbose) {
595 s->EOL();
596 s->Indent();
597 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
598
599 s->Indent();
600 s->Printf("hit count = %-4u\n", GetHitCount());
601
602 if (m_options_ap.get()) {
603 s->Indent();
604 m_options_ap->GetDescription(s, level);
605 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000606 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000607 s->IndentLess();
608 } else if (level != eDescriptionLevelInitial) {
609 s->Printf(", %sresolved, hit count = %u ", (IsResolved() ? "" : "un"),
610 GetHitCount());
611 if (m_options_ap.get()) {
612 m_options_ap->GetDescription(s, level);
613 }
614 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000615}
616
Kate Stoneb9c1b512016-09-06 20:57:50 +0000617void BreakpointLocation::Dump(Stream *s) const {
618 if (s == nullptr)
619 return;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000620
Jim Inghamaf26b222017-08-02 00:16:10 +0000621 lldb::tid_t tid = GetOptionsSpecifyingKind(BreakpointOptions::eThreadSpec)
622 ->GetThreadSpecNoCreate()->GetTID();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000623 s->Printf(
624 "BreakpointLocation %u: tid = %4.4" PRIx64 " load addr = 0x%8.8" PRIx64
625 " state = %s type = %s breakpoint "
626 "hw_index = %i hit_count = %-4u ignore_count = %-4u",
Jim Inghamaf26b222017-08-02 00:16:10 +0000627 GetID(), tid,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000628 (uint64_t)m_address.GetOpcodeLoadAddress(&m_owner.GetTarget()),
629 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled())
630 ? "enabled "
631 : "disabled",
632 IsHardware() ? "hardware" : "software", GetHardwareIndex(), GetHitCount(),
Jim Inghamaf26b222017-08-02 00:16:10 +0000633 GetOptionsSpecifyingKind(BreakpointOptions::eIgnoreCount)
634 ->GetIgnoreCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000635}
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000636
Kate Stoneb9c1b512016-09-06 20:57:50 +0000637void BreakpointLocation::SendBreakpointLocationChangedEvent(
638 lldb::BreakpointEventType eventKind) {
639 if (!m_being_created && !m_owner.IsInternal() &&
640 m_owner.GetTarget().EventTypeHasListeners(
641 Target::eBroadcastBitBreakpointChanged)) {
642 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData(
643 eventKind, m_owner.shared_from_this());
644 data->GetBreakpointLocationCollection().Add(shared_from_this());
645 m_owner.GetTarget().BroadcastEvent(Target::eBroadcastBitBreakpointChanged,
646 data);
647 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000648}
Jim Ingham77fd7382014-09-10 21:40:47 +0000649
Kate Stoneb9c1b512016-09-06 20:57:50 +0000650void BreakpointLocation::SwapLocation(BreakpointLocationSP swap_from) {
651 m_address = swap_from->m_address;
652 m_should_resolve_indirect_functions =
653 swap_from->m_should_resolve_indirect_functions;
654 m_is_reexported = swap_from->m_is_reexported;
655 m_is_indirect = swap_from->m_is_indirect;
656 m_user_expression_sp.reset();
Jim Ingham77fd7382014-09-10 21:40:47 +0000657}