blob: 2c75a11e9788477e22f397d6bcf208e6c373e3eb [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,
Jim Ingham1460e4b2014-01-10 23:46:59 +000042 bool hardware,
43 bool check_for_resolver
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044) :
Greg Claytonf3ef3d22011-05-22 22:46:53 +000045 StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware),
Jim Inghame6bc6cb2012-02-08 05:23:15 +000046 m_being_created(true),
Jim Ingham1460e4b2014-01-10 23:46:59 +000047 m_should_resolve_indirect_functions (false),
48 m_is_reexported (false),
49 m_is_indirect (false),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050 m_address (addr),
51 m_owner (owner),
52 m_options_ap (),
Sean Callananb4987e32013-06-06 20:18:50 +000053 m_bp_site_sp (),
54 m_condition_mutex ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000055{
Jim Ingham1460e4b2014-01-10 23:46:59 +000056 if (check_for_resolver)
57 {
58 Symbol *symbol = m_address.CalculateSymbolContextSymbol();
59 if (symbol && symbol->IsIndirect())
60 {
61 SetShouldResolveIndirectFunctions (true);
62 }
63 }
64
Jim Ingham1b54c882010-06-16 02:00:15 +000065 SetThreadID (tid);
Jim Inghame6bc6cb2012-02-08 05:23:15 +000066 m_being_created = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000067}
68
69BreakpointLocation::~BreakpointLocation()
70{
71 ClearBreakpointSite();
72}
73
74lldb::addr_t
Greg Clayton13238c42010-06-14 04:18:27 +000075BreakpointLocation::GetLoadAddress () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +000076{
Greg Claytonf3ef3d22011-05-22 22:46:53 +000077 return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000078}
79
80Address &
81BreakpointLocation::GetAddress ()
82{
83 return m_address;
84}
85
86Breakpoint &
87BreakpointLocation::GetBreakpoint ()
88{
89 return m_owner;
90}
91
92bool
Johnny Chenfdad6792012-02-01 19:05:20 +000093BreakpointLocation::IsEnabled () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +000094{
Johnny Chen50df1f92012-01-30 22:48:10 +000095 if (!m_owner.IsEnabled())
96 return false;
97 else if (m_options_ap.get() != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000098 return m_options_ap->IsEnabled();
99 else
Johnny Chen50df1f92012-01-30 22:48:10 +0000100 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000101}
102
103void
104BreakpointLocation::SetEnabled (bool enabled)
105{
106 GetLocationOptions()->SetEnabled(enabled);
107 if (enabled)
108 {
109 ResolveBreakpointSite();
110 }
111 else
112 {
113 ClearBreakpointSite();
114 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000115 SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000116}
117
118void
119BreakpointLocation::SetThreadID (lldb::tid_t thread_id)
120{
Jim Ingham1b54c882010-06-16 02:00:15 +0000121 if (thread_id != LLDB_INVALID_THREAD_ID)
122 GetLocationOptions()->SetThreadID(thread_id);
123 else
124 {
125 // If we're resetting this to an invalid thread id, then
126 // don't make an options pointer just to do that.
127 if (m_options_ap.get() != NULL)
128 m_options_ap->SetThreadID (thread_id);
129 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000130 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
131}
132
133lldb::tid_t
134BreakpointLocation::GetThreadID ()
135{
136 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
137 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
138 else
139 return LLDB_INVALID_THREAD_ID;
140}
141
142void
143BreakpointLocation::SetThreadIndex (uint32_t index)
144{
145 if (index != 0)
146 GetLocationOptions()->GetThreadSpec()->SetIndex(index);
147 else
148 {
149 // If we're resetting this to an invalid thread id, then
150 // don't make an options pointer just to do that.
151 if (m_options_ap.get() != NULL)
152 m_options_ap->GetThreadSpec()->SetIndex(index);
153 }
154 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
155
156}
157
158uint32_t
159BreakpointLocation::GetThreadIndex() const
160{
161 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
162 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
163 else
164 return 0;
165}
166
167void
168BreakpointLocation::SetThreadName (const char *thread_name)
169{
170 if (thread_name != NULL)
171 GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
172 else
173 {
174 // If we're resetting this to an invalid thread id, then
175 // don't make an options pointer just to do that.
176 if (m_options_ap.get() != NULL)
177 m_options_ap->GetThreadSpec()->SetName(thread_name);
178 }
179 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
180}
181
182const char *
183BreakpointLocation::GetThreadName () const
184{
185 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
186 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
187 else
188 return NULL;
189}
190
191void
192BreakpointLocation::SetQueueName (const char *queue_name)
193{
194 if (queue_name != NULL)
195 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
196 else
197 {
198 // If we're resetting this to an invalid thread id, then
199 // don't make an options pointer just to do that.
200 if (m_options_ap.get() != NULL)
201 m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
202 }
203 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
204}
205
206const char *
207BreakpointLocation::GetQueueName () const
208{
209 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
210 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
211 else
212 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000213}
214
215bool
216BreakpointLocation::InvokeCallback (StoppointCallbackContext *context)
217{
Jim Ingham01363092010-06-18 01:00:58 +0000218 if (m_options_ap.get() != NULL && m_options_ap->HasCallback())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000219 return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID());
Jim Ingham01363092010-06-18 01:00:58 +0000220 else
221 return m_owner.InvokeCallback (context, GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000222}
223
224void
225BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton,
226 bool is_synchronous)
227{
228 // The default "Baton" class will keep a copy of "baton" and won't free
229 // or delete it when it goes goes out of scope.
230 GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000231 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000232}
233
234void
235BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp,
236 bool is_synchronous)
237{
238 GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000239 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000240}
241
Jim Ingham36f3b362010-10-14 23:45:03 +0000242
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000243void
244BreakpointLocation::ClearCallback ()
245{
246 GetLocationOptions()->ClearCallback();
247}
248
Jim Ingham36f3b362010-10-14 23:45:03 +0000249void
250BreakpointLocation::SetCondition (const char *condition)
251{
252 GetLocationOptions()->SetCondition (condition);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000253 SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged);
Jim Ingham36f3b362010-10-14 23:45:03 +0000254}
255
Jim Ingham36f3b362010-10-14 23:45:03 +0000256const char *
Sean Callanan3dbf3462013-04-19 07:09:15 +0000257BreakpointLocation::GetConditionText (size_t *hash) const
Jim Ingham36f3b362010-10-14 23:45:03 +0000258{
Sean Callanan3dbf3462013-04-19 07:09:15 +0000259 return GetOptionsNoCreate()->GetConditionText(hash);
260}
261
262bool
263BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
264{
265 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Sean Callananb4987e32013-06-06 20:18:50 +0000266
267 Mutex::Locker evaluation_locker(m_condition_mutex);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000268
269 size_t condition_hash;
270 const char *condition_text = GetConditionText(&condition_hash);
271
272 if (!condition_text)
Sean Callananec537a22013-05-10 21:58:45 +0000273 {
274 m_user_expression_sp.reset();
Sean Callanan3dbf3462013-04-19 07:09:15 +0000275 return false;
Sean Callananec537a22013-05-10 21:58:45 +0000276 }
Sean Callanan3dbf3462013-04-19 07:09:15 +0000277
278 if (condition_hash != m_condition_hash ||
279 !m_user_expression_sp ||
280 !m_user_expression_sp->MatchesContext(exe_ctx))
281 {
282 m_user_expression_sp.reset(new ClangUserExpression(condition_text,
283 NULL,
284 lldb::eLanguageTypeUnknown,
285 ClangUserExpression::eResultTypeAny));
286
287 StreamString errors;
288
289 if (!m_user_expression_sp->Parse(errors,
290 exe_ctx,
291 eExecutionPolicyOnlyWhenNeeded,
292 true))
293 {
294 error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s",
295 errors.GetData());
296 m_user_expression_sp.reset();
297 return false;
298 }
299
300 m_condition_hash = condition_hash;
301 }
302
303 // We need to make sure the user sees any parse errors in their condition, so we'll hook the
304 // constructor errors up to the debugger's Async I/O.
305
306 ValueObjectSP result_value_sp;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000307
308 EvaluateExpressionOptions options;
309 options.SetUnwindOnError(true);
310 options.SetIgnoreBreakpoints(true);
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000311 options.SetTryAllThreads(true);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000312
313 Error expr_error;
314
315 StreamString execution_errors;
316
317 ClangExpressionVariableSP result_variable_sp;
318
319 ExecutionResults result_code =
320 m_user_expression_sp->Execute(execution_errors,
321 exe_ctx,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000322 options,
Sean Callanan3dbf3462013-04-19 07:09:15 +0000323 m_user_expression_sp,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000324 result_variable_sp);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000325
326 bool ret;
327
328 if (result_code == eExecutionCompleted)
329 {
Sean Callanan467441d52013-05-29 20:22:18 +0000330 if (!result_variable_sp)
331 {
332 ret = false;
333 error.SetErrorString("Expression did not return a result");
Sean Callanan879425f2013-06-24 17:58:46 +0000334 return false;
Sean Callanan467441d52013-05-29 20:22:18 +0000335 }
336
Sean Callanan3dbf3462013-04-19 07:09:15 +0000337 result_value_sp = result_variable_sp->GetValueObject();
338
339 if (result_value_sp)
340 {
341 Scalar scalar_value;
342 if (result_value_sp->ResolveValue (scalar_value))
343 {
344 if (scalar_value.ULongLong(1) == 0)
345 ret = false;
346 else
347 ret = true;
348 if (log)
349 log->Printf("Condition successfully evaluated, result is %s.\n",
350 ret ? "true" : "false");
351 }
352 else
353 {
354 ret = false;
355 error.SetErrorString("Failed to get an integer result from the expression");
356 }
357 }
358 else
359 {
360 ret = false;
361 error.SetErrorString("Failed to get any result from the expression");
362 }
363 }
364 else
365 {
366 ret = false;
367 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData());
368 }
369
370 return ret;
Jim Ingham36f3b362010-10-14 23:45:03 +0000371}
372
Greg Claytonc982c762010-07-09 20:39:50 +0000373uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000374BreakpointLocation::GetIgnoreCount ()
375{
Jim Ingham05407f62010-06-22 21:12:54 +0000376 return GetOptionsNoCreate()->GetIgnoreCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000377}
378
379void
Greg Claytonc982c762010-07-09 20:39:50 +0000380BreakpointLocation::SetIgnoreCount (uint32_t n)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000381{
382 GetLocationOptions()->SetIgnoreCount(n);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000383 SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000384}
385
Jim Ingham0fd1b752012-06-26 22:27:55 +0000386void
387BreakpointLocation::DecrementIgnoreCount()
388{
389 if (m_options_ap.get() != NULL)
390 {
391 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
392 if (loc_ignore != 0)
393 m_options_ap->SetIgnoreCount(loc_ignore - 1);
394 }
395}
396
397bool
398BreakpointLocation::IgnoreCountShouldStop()
399{
400 if (m_options_ap.get() != NULL)
401 {
402 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
403 if (loc_ignore != 0)
404 {
405 m_owner.DecrementIgnoreCount();
406 DecrementIgnoreCount(); // Have to decrement our owners' ignore count, since it won't get a
407 // chance to.
408 return false;
409 }
410 }
411 return true;
412}
413
Jim Ingham1b54c882010-06-16 02:00:15 +0000414const BreakpointOptions *
Jim Ingham05407f62010-06-22 21:12:54 +0000415BreakpointLocation::GetOptionsNoCreate () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416{
417 if (m_options_ap.get() != NULL)
418 return m_options_ap.get();
419 else
420 return m_owner.GetOptions ();
421}
422
423BreakpointOptions *
424BreakpointLocation::GetLocationOptions ()
425{
Jim Ingham01363092010-06-18 01:00:58 +0000426 // If we make the copy we don't copy the callbacks because that is potentially
427 // expensive and we don't want to do that for the simple case where someone is
428 // just disabling the location.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000429 if (m_options_ap.get() == NULL)
Jim Ingham01363092010-06-18 01:00:58 +0000430 m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ()));
431
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000432 return m_options_ap.get();
433}
434
Jim Ingham1b54c882010-06-16 02:00:15 +0000435bool
436BreakpointLocation::ValidForThisThread (Thread *thread)
437{
Jim Ingham05407f62010-06-22 21:12:54 +0000438 return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
Jim Ingham1b54c882010-06-16 02:00:15 +0000439}
440
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000441// RETURNS - true if we should stop at this breakpoint, false if we
Jim Ingham1b54c882010-06-16 02:00:15 +0000442// should continue. Note, we don't check the thread spec for the breakpoint
443// here, since if the breakpoint is not for this thread, then the event won't
444// even get reported, so the check is redundant.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000445
446bool
447BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
448{
449 bool should_stop = true;
Greg Clayton5160ce52013-03-27 23:08:40 +0000450 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000451
Johnny Chenfab7a912012-01-23 23:03:59 +0000452 IncrementHitCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000453
454 if (!IsEnabled())
455 return false;
456
Jim Ingham0fd1b752012-06-26 22:27:55 +0000457 if (!IgnoreCountShouldStop())
458 return false;
459
460 if (!m_owner.IgnoreCountShouldStop())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461 return false;
462
Jim Ingham36f3b362010-10-14 23:45:03 +0000463 // We only run synchronous callbacks in ShouldStop:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000464 context->is_synchronous = true;
465 should_stop = InvokeCallback (context);
Jim Ingham36f3b362010-10-14 23:45:03 +0000466
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000467 if (log)
Jim Ingham36f3b362010-10-14 23:45:03 +0000468 {
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000469 StreamString s;
470 GetDescription (&s, lldb::eDescriptionLevelVerbose);
471 log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000472 }
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000473
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000474 return should_stop;
475}
476
477bool
478BreakpointLocation::IsResolved () const
479{
480 return m_bp_site_sp.get() != NULL;
481}
482
Jim Ingham36f3b362010-10-14 23:45:03 +0000483lldb::BreakpointSiteSP
484BreakpointLocation::GetBreakpointSite() const
485{
486 return m_bp_site_sp;
487}
488
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000489bool
490BreakpointLocation::ResolveBreakpointSite ()
491{
492 if (m_bp_site_sp)
493 return true;
494
Greg Claytonf5e56de2010-09-14 23:36:40 +0000495 Process *process = m_owner.GetTarget().GetProcessSP().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000496 if (process == NULL)
497 return false;
498
Greg Claytoneb023e72013-10-11 19:48:25 +0000499 lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), m_owner.IsHardware());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000500
Stephen Wilson50bd94f2010-07-17 00:56:13 +0000501 if (new_id == LLDB_INVALID_BREAK_ID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000502 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000503 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000504 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000505 log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n",
Greg Claytonf3ef3d22011-05-22 22:46:53 +0000506 m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000507 return false;
508 }
509
510 return true;
511}
512
513bool
514BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp)
515{
516 m_bp_site_sp = bp_site_sp;
517 return true;
518}
519
520bool
521BreakpointLocation::ClearBreakpointSite ()
522{
523 if (m_bp_site_sp.get())
524 {
Jim Ingham01363092010-06-18 01:00:58 +0000525 m_owner.GetTarget().GetProcessSP()->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(),
526 GetID(), m_bp_site_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000527 m_bp_site_sp.reset();
528 return true;
529 }
530 return false;
531}
532
533void
534BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
535{
536 SymbolContext sc;
Jim Ingham1391cc72012-09-22 00:04:04 +0000537
538 // If the description level is "initial" then the breakpoint is printing out our initial state,
539 // and we should let it decide how it wants to print our label.
540 if (level != eDescriptionLevelInitial)
541 {
542 s->Indent();
543 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
544 }
545
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000546 if (level == lldb::eDescriptionLevelBrief)
547 return;
548
Jim Ingham1391cc72012-09-22 00:04:04 +0000549 if (level != eDescriptionLevelInitial)
550 s->PutCString(": ");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000551
552 if (level == lldb::eDescriptionLevelVerbose)
553 s->IndentMore();
554
555 if (m_address.IsSectionOffset())
556 {
557 m_address.CalculateSymbolContext(&sc);
558
Jim Ingham1391cc72012-09-22 00:04:04 +0000559 if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000560 {
Jim Ingham1460e4b2014-01-10 23:46:59 +0000561 if (IsReExported())
562 s->PutCString ("re-exported target = ");
563 else
564 s->PutCString("where = ");
Greg Clayton2cad65a2010-09-03 17:10:42 +0000565 sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000566 }
567 else
568 {
569 if (sc.module_sp)
570 {
571 s->EOL();
572 s->Indent("module = ");
573 sc.module_sp->GetFileSpec().Dump (s);
574 }
575
576 if (sc.comp_unit != NULL)
577 {
578 s->EOL();
579 s->Indent("compile unit = ");
Jim Ingham517b3b22010-10-27 22:58:34 +0000580 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000581
582 if (sc.function != NULL)
583 {
584 s->EOL();
585 s->Indent("function = ");
586 s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>"));
587 }
588
589 if (sc.line_entry.line > 0)
590 {
591 s->EOL();
592 s->Indent("location = ");
Greg Clayton6dadd502010-09-02 21:44:10 +0000593 sc.line_entry.DumpStopContext (s, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000594 }
595
596 }
597 else
598 {
599 // If we don't have a comp unit, see if we have a symbol we can print.
600 if (sc.symbol)
601 {
602 s->EOL();
Jim Ingham1460e4b2014-01-10 23:46:59 +0000603 if (IsReExported())
604 s->Indent ("re-exported target = ");
605 else
606 s->Indent("symbol = ");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000607 s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>"));
608 }
609 }
610 }
611 }
612
613 if (level == lldb::eDescriptionLevelVerbose)
614 {
615 s->EOL();
616 s->Indent();
617 }
Jim Ingham1391cc72012-09-22 00:04:04 +0000618
619 if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
620 s->Printf (", ");
621 s->Printf ("address = ");
622
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000623 ExecutionContextScope *exe_scope = NULL;
624 Target *target = &m_owner.GetTarget();
625 if (target)
626 exe_scope = target->GetProcessSP().get();
627 if (exe_scope == NULL)
628 exe_scope = target;
629
Jim Ingham1391cc72012-09-22 00:04:04 +0000630 if (eDescriptionLevelInitial)
631 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
632 else
633 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
Jim Ingham1460e4b2014-01-10 23:46:59 +0000634
635 if (IsIndirect() && m_bp_site_sp)
636 {
637 Address resolved_address;
638 resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
639 Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
640 if (resolved_symbol)
641 {
642 if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
643 s->Printf (", ");
644 else if (level == lldb::eDescriptionLevelVerbose)
645 {
646 s->EOL();
647 s->Indent();
648 }
649 s->Printf ("indirect target = %s", resolved_symbol->GetName().GetCString());
650 }
651 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000652
653 if (level == lldb::eDescriptionLevelVerbose)
654 {
655 s->EOL();
656 s->Indent();
657 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
658
659 s->Indent();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000660 s->Printf ("hit count = %-4u\n", GetHitCount());
661
662 if (m_options_ap.get())
663 {
Jim Ingham01363092010-06-18 01:00:58 +0000664 s->Indent();
665 m_options_ap->GetDescription (s, level);
666 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000667 }
668 s->IndentLess();
669 }
Jim Ingham1391cc72012-09-22 00:04:04 +0000670 else if (level != eDescriptionLevelInitial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000671 {
Jim Ingham01363092010-06-18 01:00:58 +0000672 s->Printf(", %sresolved, hit count = %u ",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000673 (IsResolved() ? "" : "un"),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000674 GetHitCount());
Jim Ingham01363092010-06-18 01:00:58 +0000675 if (m_options_ap.get())
676 {
677 m_options_ap->GetDescription (s, level);
678 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000679 }
680}
681
682void
683BreakpointLocation::Dump(Stream *s) const
684{
685 if (s == NULL)
686 return;
687
Daniel Malead01b2952012-11-29 21:49:15 +0000688 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 +0000689 "hw_index = %i hit_count = %-4u ignore_count = %-4u",
Johnny Chen9ec3c4f2012-01-26 00:08:14 +0000690 GetID(),
691 GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
692 (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()),
Johnny Chen50df1f92012-01-30 22:48:10 +0000693 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled",
Johnny Chen9ec3c4f2012-01-26 00:08:14 +0000694 IsHardware() ? "hardware" : "software",
695 GetHardwareIndex(),
696 GetHitCount(),
697 GetOptionsNoCreate()->GetIgnoreCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000698}
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000699
700void
701BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind)
702{
703 if (!m_being_created
704 && !m_owner.IsInternal()
705 && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
706 {
707 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind,
708 m_owner.shared_from_this());
709 data->GetBreakpointLocationCollection().Add (shared_from_this());
710 m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
711 }
712}
713