blob: ba8f1de8d12806372e3bb33fbf9d2c269285ca66 [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
Daniel Malea93a64302012-12-05 00:20:57 +000010#include "lldb/lldb-python.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012// C Includes
13// C++ Includes
14#include <string>
15
16// Other libraries and framework includes
17// Project includes
Greg Clayton1f746072012-08-29 21:13:06 +000018#include "lldb/lldb-private-log.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Breakpoint/BreakpointLocation.h"
20#include "lldb/Breakpoint/BreakpointID.h"
21#include "lldb/Breakpoint/StoppointCallbackContext.h"
Jim Ingham5b52f0c2011-06-02 23:58:26 +000022#include "lldb/Core/Debugger.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Core/Log.h"
Greg Clayton1f746072012-08-29 21:13:06 +000024#include "lldb/Core/Module.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Core/StreamString.h"
Greg Clayton1f746072012-08-29 21:13:06 +000026#include "lldb/Symbol/CompileUnit.h"
27#include "lldb/Symbol/Symbol.h"
28#include "lldb/Target/Target.h"
29#include "lldb/Target/Process.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
36BreakpointLocation::BreakpointLocation
37(
38 break_id_t loc_id,
39 Breakpoint &owner,
Greg Claytonc0d34462011-02-05 00:38:04 +000040 const Address &addr,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000041 lldb::tid_t tid,
42 bool hardware
43) :
Greg Claytonf3ef3d22011-05-22 22:46:53 +000044 StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware),
Jim Inghame6bc6cb2012-02-08 05:23:15 +000045 m_being_created(true),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046 m_address (addr),
47 m_owner (owner),
48 m_options_ap (),
Sean Callananb4987e32013-06-06 20:18:50 +000049 m_bp_site_sp (),
50 m_condition_mutex ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051{
Jim Ingham1b54c882010-06-16 02:00:15 +000052 SetThreadID (tid);
Jim Inghame6bc6cb2012-02-08 05:23:15 +000053 m_being_created = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054}
55
56BreakpointLocation::~BreakpointLocation()
57{
58 ClearBreakpointSite();
59}
60
61lldb::addr_t
Greg Clayton13238c42010-06-14 04:18:27 +000062BreakpointLocation::GetLoadAddress () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063{
Greg Claytonf3ef3d22011-05-22 22:46:53 +000064 return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000065}
66
67Address &
68BreakpointLocation::GetAddress ()
69{
70 return m_address;
71}
72
73Breakpoint &
74BreakpointLocation::GetBreakpoint ()
75{
76 return m_owner;
77}
78
79bool
Johnny Chenfdad6792012-02-01 19:05:20 +000080BreakpointLocation::IsEnabled () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +000081{
Johnny Chen50df1f92012-01-30 22:48:10 +000082 if (!m_owner.IsEnabled())
83 return false;
84 else if (m_options_ap.get() != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000085 return m_options_ap->IsEnabled();
86 else
Johnny Chen50df1f92012-01-30 22:48:10 +000087 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000088}
89
90void
91BreakpointLocation::SetEnabled (bool enabled)
92{
93 GetLocationOptions()->SetEnabled(enabled);
94 if (enabled)
95 {
96 ResolveBreakpointSite();
97 }
98 else
99 {
100 ClearBreakpointSite();
101 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000102 SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000103}
104
105void
106BreakpointLocation::SetThreadID (lldb::tid_t thread_id)
107{
Jim Ingham1b54c882010-06-16 02:00:15 +0000108 if (thread_id != LLDB_INVALID_THREAD_ID)
109 GetLocationOptions()->SetThreadID(thread_id);
110 else
111 {
112 // If we're resetting this to an invalid thread id, then
113 // don't make an options pointer just to do that.
114 if (m_options_ap.get() != NULL)
115 m_options_ap->SetThreadID (thread_id);
116 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000117 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
118}
119
120lldb::tid_t
121BreakpointLocation::GetThreadID ()
122{
123 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
124 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
125 else
126 return LLDB_INVALID_THREAD_ID;
127}
128
129void
130BreakpointLocation::SetThreadIndex (uint32_t index)
131{
132 if (index != 0)
133 GetLocationOptions()->GetThreadSpec()->SetIndex(index);
134 else
135 {
136 // If we're resetting this to an invalid thread id, then
137 // don't make an options pointer just to do that.
138 if (m_options_ap.get() != NULL)
139 m_options_ap->GetThreadSpec()->SetIndex(index);
140 }
141 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
142
143}
144
145uint32_t
146BreakpointLocation::GetThreadIndex() const
147{
148 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
149 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
150 else
151 return 0;
152}
153
154void
155BreakpointLocation::SetThreadName (const char *thread_name)
156{
157 if (thread_name != NULL)
158 GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
159 else
160 {
161 // If we're resetting this to an invalid thread id, then
162 // don't make an options pointer just to do that.
163 if (m_options_ap.get() != NULL)
164 m_options_ap->GetThreadSpec()->SetName(thread_name);
165 }
166 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
167}
168
169const char *
170BreakpointLocation::GetThreadName () const
171{
172 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
173 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
174 else
175 return NULL;
176}
177
178void
179BreakpointLocation::SetQueueName (const char *queue_name)
180{
181 if (queue_name != NULL)
182 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
183 else
184 {
185 // If we're resetting this to an invalid thread id, then
186 // don't make an options pointer just to do that.
187 if (m_options_ap.get() != NULL)
188 m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
189 }
190 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
191}
192
193const char *
194BreakpointLocation::GetQueueName () const
195{
196 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
197 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
198 else
199 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000200}
201
202bool
203BreakpointLocation::InvokeCallback (StoppointCallbackContext *context)
204{
Jim Ingham01363092010-06-18 01:00:58 +0000205 if (m_options_ap.get() != NULL && m_options_ap->HasCallback())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000206 return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID());
Jim Ingham01363092010-06-18 01:00:58 +0000207 else
208 return m_owner.InvokeCallback (context, GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000209}
210
211void
212BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton,
213 bool is_synchronous)
214{
215 // The default "Baton" class will keep a copy of "baton" and won't free
216 // or delete it when it goes goes out of scope.
217 GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000218 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000219}
220
221void
222BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp,
223 bool is_synchronous)
224{
225 GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000226 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000227}
228
Jim Ingham36f3b362010-10-14 23:45:03 +0000229
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000230void
231BreakpointLocation::ClearCallback ()
232{
233 GetLocationOptions()->ClearCallback();
234}
235
Jim Ingham36f3b362010-10-14 23:45:03 +0000236void
237BreakpointLocation::SetCondition (const char *condition)
238{
239 GetLocationOptions()->SetCondition (condition);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000240 SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged);
Jim Ingham36f3b362010-10-14 23:45:03 +0000241}
242
Jim Ingham36f3b362010-10-14 23:45:03 +0000243const char *
Sean Callanan3dbf3462013-04-19 07:09:15 +0000244BreakpointLocation::GetConditionText (size_t *hash) const
Jim Ingham36f3b362010-10-14 23:45:03 +0000245{
Sean Callanan3dbf3462013-04-19 07:09:15 +0000246 return GetOptionsNoCreate()->GetConditionText(hash);
247}
248
249bool
250BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
251{
252 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Sean Callananb4987e32013-06-06 20:18:50 +0000253
254 Mutex::Locker evaluation_locker(m_condition_mutex);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000255
256 size_t condition_hash;
257 const char *condition_text = GetConditionText(&condition_hash);
258
259 if (!condition_text)
Sean Callananec537a22013-05-10 21:58:45 +0000260 {
261 m_user_expression_sp.reset();
Sean Callanan3dbf3462013-04-19 07:09:15 +0000262 return false;
Sean Callananec537a22013-05-10 21:58:45 +0000263 }
Sean Callanan3dbf3462013-04-19 07:09:15 +0000264
265 if (condition_hash != m_condition_hash ||
266 !m_user_expression_sp ||
267 !m_user_expression_sp->MatchesContext(exe_ctx))
268 {
269 m_user_expression_sp.reset(new ClangUserExpression(condition_text,
270 NULL,
271 lldb::eLanguageTypeUnknown,
272 ClangUserExpression::eResultTypeAny));
273
274 StreamString errors;
275
276 if (!m_user_expression_sp->Parse(errors,
277 exe_ctx,
278 eExecutionPolicyOnlyWhenNeeded,
279 true))
280 {
281 error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s",
282 errors.GetData());
283 m_user_expression_sp.reset();
284 return false;
285 }
286
287 m_condition_hash = condition_hash;
288 }
289
290 // We need to make sure the user sees any parse errors in their condition, so we'll hook the
291 // constructor errors up to the debugger's Async I/O.
292
293 ValueObjectSP result_value_sp;
294 const bool unwind_on_error = true;
295 const bool ignore_breakpoints = true;
296 const bool try_all_threads = true;
297
298 Error expr_error;
299
300 StreamString execution_errors;
301
302 ClangExpressionVariableSP result_variable_sp;
303
304 ExecutionResults result_code =
305 m_user_expression_sp->Execute(execution_errors,
306 exe_ctx,
307 unwind_on_error,
308 ignore_breakpoints,
309 m_user_expression_sp,
310 result_variable_sp,
311 try_all_threads,
312 ClangUserExpression::kDefaultTimeout);
313
314 bool ret;
315
316 if (result_code == eExecutionCompleted)
317 {
Sean Callanan467441d52013-05-29 20:22:18 +0000318 if (!result_variable_sp)
319 {
320 ret = false;
321 error.SetErrorString("Expression did not return a result");
322 }
323
Sean Callanan3dbf3462013-04-19 07:09:15 +0000324 result_value_sp = result_variable_sp->GetValueObject();
325
326 if (result_value_sp)
327 {
328 Scalar scalar_value;
329 if (result_value_sp->ResolveValue (scalar_value))
330 {
331 if (scalar_value.ULongLong(1) == 0)
332 ret = false;
333 else
334 ret = true;
335 if (log)
336 log->Printf("Condition successfully evaluated, result is %s.\n",
337 ret ? "true" : "false");
338 }
339 else
340 {
341 ret = false;
342 error.SetErrorString("Failed to get an integer result from the expression");
343 }
344 }
345 else
346 {
347 ret = false;
348 error.SetErrorString("Failed to get any result from the expression");
349 }
350 }
351 else
352 {
353 ret = false;
354 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData());
355 }
356
357 return ret;
Jim Ingham36f3b362010-10-14 23:45:03 +0000358}
359
Greg Claytonc982c762010-07-09 20:39:50 +0000360uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361BreakpointLocation::GetIgnoreCount ()
362{
Jim Ingham05407f62010-06-22 21:12:54 +0000363 return GetOptionsNoCreate()->GetIgnoreCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000364}
365
366void
Greg Claytonc982c762010-07-09 20:39:50 +0000367BreakpointLocation::SetIgnoreCount (uint32_t n)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000368{
369 GetLocationOptions()->SetIgnoreCount(n);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000370 SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000371}
372
Jim Ingham0fd1b752012-06-26 22:27:55 +0000373void
374BreakpointLocation::DecrementIgnoreCount()
375{
376 if (m_options_ap.get() != NULL)
377 {
378 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
379 if (loc_ignore != 0)
380 m_options_ap->SetIgnoreCount(loc_ignore - 1);
381 }
382}
383
384bool
385BreakpointLocation::IgnoreCountShouldStop()
386{
387 if (m_options_ap.get() != NULL)
388 {
389 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
390 if (loc_ignore != 0)
391 {
392 m_owner.DecrementIgnoreCount();
393 DecrementIgnoreCount(); // Have to decrement our owners' ignore count, since it won't get a
394 // chance to.
395 return false;
396 }
397 }
398 return true;
399}
400
Jim Ingham1b54c882010-06-16 02:00:15 +0000401const BreakpointOptions *
Jim Ingham05407f62010-06-22 21:12:54 +0000402BreakpointLocation::GetOptionsNoCreate () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000403{
404 if (m_options_ap.get() != NULL)
405 return m_options_ap.get();
406 else
407 return m_owner.GetOptions ();
408}
409
410BreakpointOptions *
411BreakpointLocation::GetLocationOptions ()
412{
Jim Ingham01363092010-06-18 01:00:58 +0000413 // If we make the copy we don't copy the callbacks because that is potentially
414 // expensive and we don't want to do that for the simple case where someone is
415 // just disabling the location.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416 if (m_options_ap.get() == NULL)
Jim Ingham01363092010-06-18 01:00:58 +0000417 m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ()));
418
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000419 return m_options_ap.get();
420}
421
Jim Ingham1b54c882010-06-16 02:00:15 +0000422bool
423BreakpointLocation::ValidForThisThread (Thread *thread)
424{
Jim Ingham05407f62010-06-22 21:12:54 +0000425 return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
Jim Ingham1b54c882010-06-16 02:00:15 +0000426}
427
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000428// RETURNS - true if we should stop at this breakpoint, false if we
Jim Ingham1b54c882010-06-16 02:00:15 +0000429// should continue. Note, we don't check the thread spec for the breakpoint
430// here, since if the breakpoint is not for this thread, then the event won't
431// even get reported, so the check is redundant.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000432
433bool
434BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
435{
436 bool should_stop = true;
Greg Clayton5160ce52013-03-27 23:08:40 +0000437 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000438
Johnny Chenfab7a912012-01-23 23:03:59 +0000439 IncrementHitCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000440
441 if (!IsEnabled())
442 return false;
443
Jim Ingham0fd1b752012-06-26 22:27:55 +0000444 if (!IgnoreCountShouldStop())
445 return false;
446
447 if (!m_owner.IgnoreCountShouldStop())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000448 return false;
449
Jim Ingham36f3b362010-10-14 23:45:03 +0000450 // We only run synchronous callbacks in ShouldStop:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000451 context->is_synchronous = true;
452 should_stop = InvokeCallback (context);
Jim Ingham36f3b362010-10-14 23:45:03 +0000453
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000454 if (log)
Jim Ingham36f3b362010-10-14 23:45:03 +0000455 {
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000456 StreamString s;
457 GetDescription (&s, lldb::eDescriptionLevelVerbose);
458 log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000459 }
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000460
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461 return should_stop;
462}
463
464bool
465BreakpointLocation::IsResolved () const
466{
467 return m_bp_site_sp.get() != NULL;
468}
469
Jim Ingham36f3b362010-10-14 23:45:03 +0000470lldb::BreakpointSiteSP
471BreakpointLocation::GetBreakpointSite() const
472{
473 return m_bp_site_sp;
474}
475
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000476bool
477BreakpointLocation::ResolveBreakpointSite ()
478{
479 if (m_bp_site_sp)
480 return true;
481
Greg Claytonf5e56de2010-09-14 23:36:40 +0000482 Process *process = m_owner.GetTarget().GetProcessSP().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000483 if (process == NULL)
484 return false;
485
Greg Claytonf5e56de2010-09-14 23:36:40 +0000486 if (m_owner.GetTarget().GetSectionLoadList().IsEmpty())
487 return false;
488
Greg Claytone1cd1be2012-01-29 20:56:30 +0000489 lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000490
Stephen Wilson50bd94f2010-07-17 00:56:13 +0000491 if (new_id == LLDB_INVALID_BREAK_ID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000492 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000493 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000494 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000495 log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n",
Greg Claytonf3ef3d22011-05-22 22:46:53 +0000496 m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000497 return false;
498 }
499
500 return true;
501}
502
503bool
504BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp)
505{
506 m_bp_site_sp = bp_site_sp;
507 return true;
508}
509
510bool
511BreakpointLocation::ClearBreakpointSite ()
512{
513 if (m_bp_site_sp.get())
514 {
Jim Ingham01363092010-06-18 01:00:58 +0000515 m_owner.GetTarget().GetProcessSP()->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(),
516 GetID(), m_bp_site_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000517 m_bp_site_sp.reset();
518 return true;
519 }
520 return false;
521}
522
523void
524BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
525{
526 SymbolContext sc;
Jim Ingham1391cc72012-09-22 00:04:04 +0000527
528 // If the description level is "initial" then the breakpoint is printing out our initial state,
529 // and we should let it decide how it wants to print our label.
530 if (level != eDescriptionLevelInitial)
531 {
532 s->Indent();
533 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
534 }
535
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000536 if (level == lldb::eDescriptionLevelBrief)
537 return;
538
Jim Ingham1391cc72012-09-22 00:04:04 +0000539 if (level != eDescriptionLevelInitial)
540 s->PutCString(": ");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000541
542 if (level == lldb::eDescriptionLevelVerbose)
543 s->IndentMore();
544
545 if (m_address.IsSectionOffset())
546 {
547 m_address.CalculateSymbolContext(&sc);
548
Jim Ingham1391cc72012-09-22 00:04:04 +0000549 if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000550 {
551 s->PutCString("where = ");
Greg Clayton2cad65a2010-09-03 17:10:42 +0000552 sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000553 }
554 else
555 {
556 if (sc.module_sp)
557 {
558 s->EOL();
559 s->Indent("module = ");
560 sc.module_sp->GetFileSpec().Dump (s);
561 }
562
563 if (sc.comp_unit != NULL)
564 {
565 s->EOL();
566 s->Indent("compile unit = ");
Jim Ingham517b3b22010-10-27 22:58:34 +0000567 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000568
569 if (sc.function != NULL)
570 {
571 s->EOL();
572 s->Indent("function = ");
573 s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>"));
574 }
575
576 if (sc.line_entry.line > 0)
577 {
578 s->EOL();
579 s->Indent("location = ");
Greg Clayton6dadd502010-09-02 21:44:10 +0000580 sc.line_entry.DumpStopContext (s, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000581 }
582
583 }
584 else
585 {
586 // If we don't have a comp unit, see if we have a symbol we can print.
587 if (sc.symbol)
588 {
589 s->EOL();
590 s->Indent("symbol = ");
591 s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>"));
592 }
593 }
594 }
595 }
596
597 if (level == lldb::eDescriptionLevelVerbose)
598 {
599 s->EOL();
600 s->Indent();
601 }
Jim Ingham1391cc72012-09-22 00:04:04 +0000602
603 if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
604 s->Printf (", ");
605 s->Printf ("address = ");
606
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000607 ExecutionContextScope *exe_scope = NULL;
608 Target *target = &m_owner.GetTarget();
609 if (target)
610 exe_scope = target->GetProcessSP().get();
611 if (exe_scope == NULL)
612 exe_scope = target;
613
Jim Ingham1391cc72012-09-22 00:04:04 +0000614 if (eDescriptionLevelInitial)
615 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
616 else
617 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000618
619 if (level == lldb::eDescriptionLevelVerbose)
620 {
621 s->EOL();
622 s->Indent();
623 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
624
625 s->Indent();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000626 s->Printf ("hit count = %-4u\n", GetHitCount());
627
628 if (m_options_ap.get())
629 {
Jim Ingham01363092010-06-18 01:00:58 +0000630 s->Indent();
631 m_options_ap->GetDescription (s, level);
632 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000633 }
634 s->IndentLess();
635 }
Jim Ingham1391cc72012-09-22 00:04:04 +0000636 else if (level != eDescriptionLevelInitial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000637 {
Jim Ingham01363092010-06-18 01:00:58 +0000638 s->Printf(", %sresolved, hit count = %u ",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000639 (IsResolved() ? "" : "un"),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000640 GetHitCount());
Jim Ingham01363092010-06-18 01:00:58 +0000641 if (m_options_ap.get())
642 {
643 m_options_ap->GetDescription (s, level);
644 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000645 }
646}
647
648void
649BreakpointLocation::Dump(Stream *s) const
650{
651 if (s == NULL)
652 return;
653
Daniel Malead01b2952012-11-29 21:49:15 +0000654 s->Printf("BreakpointLocation %u: tid = %4.4" PRIx64 " load addr = 0x%8.8" PRIx64 " state = %s type = %s breakpoint "
Jim Ingham01363092010-06-18 01:00:58 +0000655 "hw_index = %i hit_count = %-4u ignore_count = %-4u",
Johnny Chen9ec3c4f2012-01-26 00:08:14 +0000656 GetID(),
657 GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
658 (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()),
Johnny Chen50df1f92012-01-30 22:48:10 +0000659 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled",
Johnny Chen9ec3c4f2012-01-26 00:08:14 +0000660 IsHardware() ? "hardware" : "software",
661 GetHardwareIndex(),
662 GetHitCount(),
663 GetOptionsNoCreate()->GetIgnoreCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000664}
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000665
666void
667BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind)
668{
669 if (!m_being_created
670 && !m_owner.IsInternal()
671 && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
672 {
673 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind,
674 m_owner.shared_from_this());
675 data->GetBreakpointLocationCollection().Add (shared_from_this());
676 m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
677 }
678}
679