blob: a473ae994066d7ee71da23c2136705bb842771ea [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 (),
49 m_bp_site_sp ()
50{
Jim Ingham1b54c882010-06-16 02:00:15 +000051 SetThreadID (tid);
Jim Inghame6bc6cb2012-02-08 05:23:15 +000052 m_being_created = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000053}
54
55BreakpointLocation::~BreakpointLocation()
56{
57 ClearBreakpointSite();
58}
59
60lldb::addr_t
Greg Clayton13238c42010-06-14 04:18:27 +000061BreakpointLocation::GetLoadAddress () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +000062{
Greg Claytonf3ef3d22011-05-22 22:46:53 +000063 return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000064}
65
66Address &
67BreakpointLocation::GetAddress ()
68{
69 return m_address;
70}
71
72Breakpoint &
73BreakpointLocation::GetBreakpoint ()
74{
75 return m_owner;
76}
77
78bool
Johnny Chenfdad6792012-02-01 19:05:20 +000079BreakpointLocation::IsEnabled () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080{
Johnny Chen50df1f92012-01-30 22:48:10 +000081 if (!m_owner.IsEnabled())
82 return false;
83 else if (m_options_ap.get() != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000084 return m_options_ap->IsEnabled();
85 else
Johnny Chen50df1f92012-01-30 22:48:10 +000086 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000087}
88
89void
90BreakpointLocation::SetEnabled (bool enabled)
91{
92 GetLocationOptions()->SetEnabled(enabled);
93 if (enabled)
94 {
95 ResolveBreakpointSite();
96 }
97 else
98 {
99 ClearBreakpointSite();
100 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000101 SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000102}
103
104void
105BreakpointLocation::SetThreadID (lldb::tid_t thread_id)
106{
Jim Ingham1b54c882010-06-16 02:00:15 +0000107 if (thread_id != LLDB_INVALID_THREAD_ID)
108 GetLocationOptions()->SetThreadID(thread_id);
109 else
110 {
111 // If we're resetting this to an invalid thread id, then
112 // don't make an options pointer just to do that.
113 if (m_options_ap.get() != NULL)
114 m_options_ap->SetThreadID (thread_id);
115 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000116 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
117}
118
119lldb::tid_t
120BreakpointLocation::GetThreadID ()
121{
122 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
123 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
124 else
125 return LLDB_INVALID_THREAD_ID;
126}
127
128void
129BreakpointLocation::SetThreadIndex (uint32_t index)
130{
131 if (index != 0)
132 GetLocationOptions()->GetThreadSpec()->SetIndex(index);
133 else
134 {
135 // If we're resetting this to an invalid thread id, then
136 // don't make an options pointer just to do that.
137 if (m_options_ap.get() != NULL)
138 m_options_ap->GetThreadSpec()->SetIndex(index);
139 }
140 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
141
142}
143
144uint32_t
145BreakpointLocation::GetThreadIndex() const
146{
147 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
148 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
149 else
150 return 0;
151}
152
153void
154BreakpointLocation::SetThreadName (const char *thread_name)
155{
156 if (thread_name != NULL)
157 GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
158 else
159 {
160 // If we're resetting this to an invalid thread id, then
161 // don't make an options pointer just to do that.
162 if (m_options_ap.get() != NULL)
163 m_options_ap->GetThreadSpec()->SetName(thread_name);
164 }
165 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
166}
167
168const char *
169BreakpointLocation::GetThreadName () const
170{
171 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
172 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
173 else
174 return NULL;
175}
176
177void
178BreakpointLocation::SetQueueName (const char *queue_name)
179{
180 if (queue_name != NULL)
181 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
182 else
183 {
184 // If we're resetting this to an invalid thread id, then
185 // don't make an options pointer just to do that.
186 if (m_options_ap.get() != NULL)
187 m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
188 }
189 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
190}
191
192const char *
193BreakpointLocation::GetQueueName () const
194{
195 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
196 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
197 else
198 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000199}
200
201bool
202BreakpointLocation::InvokeCallback (StoppointCallbackContext *context)
203{
Jim Ingham01363092010-06-18 01:00:58 +0000204 if (m_options_ap.get() != NULL && m_options_ap->HasCallback())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000205 return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID());
Jim Ingham01363092010-06-18 01:00:58 +0000206 else
207 return m_owner.InvokeCallback (context, GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000208}
209
210void
211BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton,
212 bool is_synchronous)
213{
214 // The default "Baton" class will keep a copy of "baton" and won't free
215 // or delete it when it goes goes out of scope.
216 GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000217 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000218}
219
220void
221BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp,
222 bool is_synchronous)
223{
224 GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000225 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000226}
227
Jim Ingham36f3b362010-10-14 23:45:03 +0000228
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000229void
230BreakpointLocation::ClearCallback ()
231{
232 GetLocationOptions()->ClearCallback();
233}
234
Jim Ingham36f3b362010-10-14 23:45:03 +0000235void
236BreakpointLocation::SetCondition (const char *condition)
237{
238 GetLocationOptions()->SetCondition (condition);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000239 SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged);
Jim Ingham36f3b362010-10-14 23:45:03 +0000240}
241
Jim Ingham36f3b362010-10-14 23:45:03 +0000242const char *
Sean Callanan3dbf3462013-04-19 07:09:15 +0000243BreakpointLocation::GetConditionText (size_t *hash) const
Jim Ingham36f3b362010-10-14 23:45:03 +0000244{
Sean Callanan3dbf3462013-04-19 07:09:15 +0000245 return GetOptionsNoCreate()->GetConditionText(hash);
246}
247
248bool
249BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
250{
251 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
252
253 size_t condition_hash;
254 const char *condition_text = GetConditionText(&condition_hash);
255
256 if (!condition_text)
Sean Callananec537a22013-05-10 21:58:45 +0000257 {
258 m_user_expression_sp.reset();
Sean Callanan3dbf3462013-04-19 07:09:15 +0000259 return false;
Sean Callananec537a22013-05-10 21:58:45 +0000260 }
Sean Callanan3dbf3462013-04-19 07:09:15 +0000261
262 if (condition_hash != m_condition_hash ||
263 !m_user_expression_sp ||
264 !m_user_expression_sp->MatchesContext(exe_ctx))
265 {
266 m_user_expression_sp.reset(new ClangUserExpression(condition_text,
267 NULL,
268 lldb::eLanguageTypeUnknown,
269 ClangUserExpression::eResultTypeAny));
270
271 StreamString errors;
272
273 if (!m_user_expression_sp->Parse(errors,
274 exe_ctx,
275 eExecutionPolicyOnlyWhenNeeded,
276 true))
277 {
278 error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s",
279 errors.GetData());
280 m_user_expression_sp.reset();
281 return false;
282 }
283
284 m_condition_hash = condition_hash;
285 }
286
287 // We need to make sure the user sees any parse errors in their condition, so we'll hook the
288 // constructor errors up to the debugger's Async I/O.
289
290 ValueObjectSP result_value_sp;
291 const bool unwind_on_error = true;
292 const bool ignore_breakpoints = true;
293 const bool try_all_threads = true;
294
295 Error expr_error;
296
297 StreamString execution_errors;
298
299 ClangExpressionVariableSP result_variable_sp;
300
301 ExecutionResults result_code =
302 m_user_expression_sp->Execute(execution_errors,
303 exe_ctx,
304 unwind_on_error,
305 ignore_breakpoints,
306 m_user_expression_sp,
307 result_variable_sp,
308 try_all_threads,
309 ClangUserExpression::kDefaultTimeout);
310
311 bool ret;
312
313 if (result_code == eExecutionCompleted)
314 {
Sean Callanan467441d52013-05-29 20:22:18 +0000315 if (!result_variable_sp)
316 {
317 ret = false;
318 error.SetErrorString("Expression did not return a result");
319 }
320
Sean Callanan3dbf3462013-04-19 07:09:15 +0000321 result_value_sp = result_variable_sp->GetValueObject();
322
323 if (result_value_sp)
324 {
325 Scalar scalar_value;
326 if (result_value_sp->ResolveValue (scalar_value))
327 {
328 if (scalar_value.ULongLong(1) == 0)
329 ret = false;
330 else
331 ret = true;
332 if (log)
333 log->Printf("Condition successfully evaluated, result is %s.\n",
334 ret ? "true" : "false");
335 }
336 else
337 {
338 ret = false;
339 error.SetErrorString("Failed to get an integer result from the expression");
340 }
341 }
342 else
343 {
344 ret = false;
345 error.SetErrorString("Failed to get any result from the expression");
346 }
347 }
348 else
349 {
350 ret = false;
351 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData());
352 }
353
354 return ret;
Jim Ingham36f3b362010-10-14 23:45:03 +0000355}
356
Greg Claytonc982c762010-07-09 20:39:50 +0000357uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000358BreakpointLocation::GetIgnoreCount ()
359{
Jim Ingham05407f62010-06-22 21:12:54 +0000360 return GetOptionsNoCreate()->GetIgnoreCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361}
362
363void
Greg Claytonc982c762010-07-09 20:39:50 +0000364BreakpointLocation::SetIgnoreCount (uint32_t n)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000365{
366 GetLocationOptions()->SetIgnoreCount(n);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000367 SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000368}
369
Jim Ingham0fd1b752012-06-26 22:27:55 +0000370void
371BreakpointLocation::DecrementIgnoreCount()
372{
373 if (m_options_ap.get() != NULL)
374 {
375 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
376 if (loc_ignore != 0)
377 m_options_ap->SetIgnoreCount(loc_ignore - 1);
378 }
379}
380
381bool
382BreakpointLocation::IgnoreCountShouldStop()
383{
384 if (m_options_ap.get() != NULL)
385 {
386 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
387 if (loc_ignore != 0)
388 {
389 m_owner.DecrementIgnoreCount();
390 DecrementIgnoreCount(); // Have to decrement our owners' ignore count, since it won't get a
391 // chance to.
392 return false;
393 }
394 }
395 return true;
396}
397
Jim Ingham1b54c882010-06-16 02:00:15 +0000398const BreakpointOptions *
Jim Ingham05407f62010-06-22 21:12:54 +0000399BreakpointLocation::GetOptionsNoCreate () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000400{
401 if (m_options_ap.get() != NULL)
402 return m_options_ap.get();
403 else
404 return m_owner.GetOptions ();
405}
406
407BreakpointOptions *
408BreakpointLocation::GetLocationOptions ()
409{
Jim Ingham01363092010-06-18 01:00:58 +0000410 // If we make the copy we don't copy the callbacks because that is potentially
411 // expensive and we don't want to do that for the simple case where someone is
412 // just disabling the location.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000413 if (m_options_ap.get() == NULL)
Jim Ingham01363092010-06-18 01:00:58 +0000414 m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ()));
415
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416 return m_options_ap.get();
417}
418
Jim Ingham1b54c882010-06-16 02:00:15 +0000419bool
420BreakpointLocation::ValidForThisThread (Thread *thread)
421{
Jim Ingham05407f62010-06-22 21:12:54 +0000422 return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
Jim Ingham1b54c882010-06-16 02:00:15 +0000423}
424
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000425// RETURNS - true if we should stop at this breakpoint, false if we
Jim Ingham1b54c882010-06-16 02:00:15 +0000426// should continue. Note, we don't check the thread spec for the breakpoint
427// here, since if the breakpoint is not for this thread, then the event won't
428// even get reported, so the check is redundant.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000429
430bool
431BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
432{
433 bool should_stop = true;
Greg Clayton5160ce52013-03-27 23:08:40 +0000434 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000435
Johnny Chenfab7a912012-01-23 23:03:59 +0000436 IncrementHitCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000437
438 if (!IsEnabled())
439 return false;
440
Jim Ingham0fd1b752012-06-26 22:27:55 +0000441 if (!IgnoreCountShouldStop())
442 return false;
443
444 if (!m_owner.IgnoreCountShouldStop())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000445 return false;
446
Jim Ingham36f3b362010-10-14 23:45:03 +0000447 // We only run synchronous callbacks in ShouldStop:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000448 context->is_synchronous = true;
449 should_stop = InvokeCallback (context);
Jim Ingham36f3b362010-10-14 23:45:03 +0000450
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000451 if (log)
Jim Ingham36f3b362010-10-14 23:45:03 +0000452 {
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000453 StreamString s;
454 GetDescription (&s, lldb::eDescriptionLevelVerbose);
455 log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456 }
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000457
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000458 return should_stop;
459}
460
461bool
462BreakpointLocation::IsResolved () const
463{
464 return m_bp_site_sp.get() != NULL;
465}
466
Jim Ingham36f3b362010-10-14 23:45:03 +0000467lldb::BreakpointSiteSP
468BreakpointLocation::GetBreakpointSite() const
469{
470 return m_bp_site_sp;
471}
472
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000473bool
474BreakpointLocation::ResolveBreakpointSite ()
475{
476 if (m_bp_site_sp)
477 return true;
478
Greg Claytonf5e56de2010-09-14 23:36:40 +0000479 Process *process = m_owner.GetTarget().GetProcessSP().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000480 if (process == NULL)
481 return false;
482
Greg Claytonf5e56de2010-09-14 23:36:40 +0000483 if (m_owner.GetTarget().GetSectionLoadList().IsEmpty())
484 return false;
485
Greg Claytone1cd1be2012-01-29 20:56:30 +0000486 lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000487
Stephen Wilson50bd94f2010-07-17 00:56:13 +0000488 if (new_id == LLDB_INVALID_BREAK_ID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000489 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000490 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000491 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000492 log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n",
Greg Claytonf3ef3d22011-05-22 22:46:53 +0000493 m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000494 return false;
495 }
496
497 return true;
498}
499
500bool
501BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp)
502{
503 m_bp_site_sp = bp_site_sp;
504 return true;
505}
506
507bool
508BreakpointLocation::ClearBreakpointSite ()
509{
510 if (m_bp_site_sp.get())
511 {
Jim Ingham01363092010-06-18 01:00:58 +0000512 m_owner.GetTarget().GetProcessSP()->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(),
513 GetID(), m_bp_site_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000514 m_bp_site_sp.reset();
515 return true;
516 }
517 return false;
518}
519
520void
521BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
522{
523 SymbolContext sc;
Jim Ingham1391cc72012-09-22 00:04:04 +0000524
525 // If the description level is "initial" then the breakpoint is printing out our initial state,
526 // and we should let it decide how it wants to print our label.
527 if (level != eDescriptionLevelInitial)
528 {
529 s->Indent();
530 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
531 }
532
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000533 if (level == lldb::eDescriptionLevelBrief)
534 return;
535
Jim Ingham1391cc72012-09-22 00:04:04 +0000536 if (level != eDescriptionLevelInitial)
537 s->PutCString(": ");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000538
539 if (level == lldb::eDescriptionLevelVerbose)
540 s->IndentMore();
541
542 if (m_address.IsSectionOffset())
543 {
544 m_address.CalculateSymbolContext(&sc);
545
Jim Ingham1391cc72012-09-22 00:04:04 +0000546 if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000547 {
548 s->PutCString("where = ");
Greg Clayton2cad65a2010-09-03 17:10:42 +0000549 sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000550 }
551 else
552 {
553 if (sc.module_sp)
554 {
555 s->EOL();
556 s->Indent("module = ");
557 sc.module_sp->GetFileSpec().Dump (s);
558 }
559
560 if (sc.comp_unit != NULL)
561 {
562 s->EOL();
563 s->Indent("compile unit = ");
Jim Ingham517b3b22010-10-27 22:58:34 +0000564 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000565
566 if (sc.function != NULL)
567 {
568 s->EOL();
569 s->Indent("function = ");
570 s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>"));
571 }
572
573 if (sc.line_entry.line > 0)
574 {
575 s->EOL();
576 s->Indent("location = ");
Greg Clayton6dadd502010-09-02 21:44:10 +0000577 sc.line_entry.DumpStopContext (s, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000578 }
579
580 }
581 else
582 {
583 // If we don't have a comp unit, see if we have a symbol we can print.
584 if (sc.symbol)
585 {
586 s->EOL();
587 s->Indent("symbol = ");
588 s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>"));
589 }
590 }
591 }
592 }
593
594 if (level == lldb::eDescriptionLevelVerbose)
595 {
596 s->EOL();
597 s->Indent();
598 }
Jim Ingham1391cc72012-09-22 00:04:04 +0000599
600 if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
601 s->Printf (", ");
602 s->Printf ("address = ");
603
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000604 ExecutionContextScope *exe_scope = NULL;
605 Target *target = &m_owner.GetTarget();
606 if (target)
607 exe_scope = target->GetProcessSP().get();
608 if (exe_scope == NULL)
609 exe_scope = target;
610
Jim Ingham1391cc72012-09-22 00:04:04 +0000611 if (eDescriptionLevelInitial)
612 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
613 else
614 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000615
616 if (level == lldb::eDescriptionLevelVerbose)
617 {
618 s->EOL();
619 s->Indent();
620 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
621
622 s->Indent();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000623 s->Printf ("hit count = %-4u\n", GetHitCount());
624
625 if (m_options_ap.get())
626 {
Jim Ingham01363092010-06-18 01:00:58 +0000627 s->Indent();
628 m_options_ap->GetDescription (s, level);
629 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000630 }
631 s->IndentLess();
632 }
Jim Ingham1391cc72012-09-22 00:04:04 +0000633 else if (level != eDescriptionLevelInitial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000634 {
Jim Ingham01363092010-06-18 01:00:58 +0000635 s->Printf(", %sresolved, hit count = %u ",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000636 (IsResolved() ? "" : "un"),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000637 GetHitCount());
Jim Ingham01363092010-06-18 01:00:58 +0000638 if (m_options_ap.get())
639 {
640 m_options_ap->GetDescription (s, level);
641 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000642 }
643}
644
645void
646BreakpointLocation::Dump(Stream *s) const
647{
648 if (s == NULL)
649 return;
650
Daniel Malead01b2952012-11-29 21:49:15 +0000651 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 +0000652 "hw_index = %i hit_count = %-4u ignore_count = %-4u",
Johnny Chen9ec3c4f2012-01-26 00:08:14 +0000653 GetID(),
654 GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
655 (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()),
Johnny Chen50df1f92012-01-30 22:48:10 +0000656 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled",
Johnny Chen9ec3c4f2012-01-26 00:08:14 +0000657 IsHardware() ? "hardware" : "software",
658 GetHardwareIndex(),
659 GetHitCount(),
660 GetOptionsNoCreate()->GetIgnoreCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000661}
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000662
663void
664BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind)
665{
666 if (!m_being_created
667 && !m_owner.IsInternal()
668 && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
669 {
670 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind,
671 m_owner.shared_from_this());
672 data->GetBreakpointLocationCollection().Add (shared_from_this());
673 m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
674 }
675}
676