blob: af868dca07c59f01ea6c093ef8289ed82da273a4 [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"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000026#include "lldb/Core/ValueObject.h"
Zachary Turnerfc858812015-03-04 17:43:00 +000027#include "lldb/Expression/ClangUserExpression.h"
Greg Clayton1f746072012-08-29 21:13:06 +000028#include "lldb/Symbol/CompileUnit.h"
29#include "lldb/Symbol/Symbol.h"
30#include "lldb/Target/Target.h"
31#include "lldb/Target/Process.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032#include "lldb/Target/Thread.h"
Jim Ingham1b54c882010-06-16 02:00:15 +000033#include "lldb/Target/ThreadSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034
35using namespace lldb;
36using namespace lldb_private;
37
38BreakpointLocation::BreakpointLocation
39(
40 break_id_t loc_id,
41 Breakpoint &owner,
Greg Claytonc0d34462011-02-05 00:38:04 +000042 const Address &addr,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043 lldb::tid_t tid,
Jim Ingham1460e4b2014-01-10 23:46:59 +000044 bool hardware,
45 bool check_for_resolver
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046) :
Greg Claytonf3ef3d22011-05-22 22:46:53 +000047 StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware),
Jim Inghame6bc6cb2012-02-08 05:23:15 +000048 m_being_created(true),
Jim Ingham1460e4b2014-01-10 23:46:59 +000049 m_should_resolve_indirect_functions (false),
50 m_is_reexported (false),
51 m_is_indirect (false),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052 m_address (addr),
53 m_owner (owner),
54 m_options_ap (),
Sean Callananb4987e32013-06-06 20:18:50 +000055 m_bp_site_sp (),
56 m_condition_mutex ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057{
Jim Ingham1460e4b2014-01-10 23:46:59 +000058 if (check_for_resolver)
59 {
60 Symbol *symbol = m_address.CalculateSymbolContextSymbol();
61 if (symbol && symbol->IsIndirect())
62 {
63 SetShouldResolveIndirectFunctions (true);
64 }
65 }
66
Jim Ingham1b54c882010-06-16 02:00:15 +000067 SetThreadID (tid);
Jim Inghame6bc6cb2012-02-08 05:23:15 +000068 m_being_created = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000069}
70
71BreakpointLocation::~BreakpointLocation()
72{
73 ClearBreakpointSite();
74}
75
76lldb::addr_t
Greg Clayton13238c42010-06-14 04:18:27 +000077BreakpointLocation::GetLoadAddress () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +000078{
Greg Claytonf3ef3d22011-05-22 22:46:53 +000079 return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000080}
81
82Address &
83BreakpointLocation::GetAddress ()
84{
85 return m_address;
86}
87
88Breakpoint &
89BreakpointLocation::GetBreakpoint ()
90{
91 return m_owner;
92}
93
94bool
Johnny Chenfdad6792012-02-01 19:05:20 +000095BreakpointLocation::IsEnabled () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +000096{
Johnny Chen50df1f92012-01-30 22:48:10 +000097 if (!m_owner.IsEnabled())
98 return false;
99 else if (m_options_ap.get() != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000100 return m_options_ap->IsEnabled();
101 else
Johnny Chen50df1f92012-01-30 22:48:10 +0000102 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000103}
104
105void
106BreakpointLocation::SetEnabled (bool enabled)
107{
108 GetLocationOptions()->SetEnabled(enabled);
109 if (enabled)
110 {
111 ResolveBreakpointSite();
112 }
113 else
114 {
115 ClearBreakpointSite();
116 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000117 SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000118}
119
120void
121BreakpointLocation::SetThreadID (lldb::tid_t thread_id)
122{
Jim Ingham1b54c882010-06-16 02:00:15 +0000123 if (thread_id != LLDB_INVALID_THREAD_ID)
124 GetLocationOptions()->SetThreadID(thread_id);
125 else
126 {
127 // If we're resetting this to an invalid thread id, then
128 // don't make an options pointer just to do that.
129 if (m_options_ap.get() != NULL)
130 m_options_ap->SetThreadID (thread_id);
131 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000132 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
133}
134
135lldb::tid_t
136BreakpointLocation::GetThreadID ()
137{
138 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
139 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
140 else
141 return LLDB_INVALID_THREAD_ID;
142}
143
144void
145BreakpointLocation::SetThreadIndex (uint32_t index)
146{
147 if (index != 0)
148 GetLocationOptions()->GetThreadSpec()->SetIndex(index);
149 else
150 {
151 // If we're resetting this to an invalid thread id, then
152 // don't make an options pointer just to do that.
153 if (m_options_ap.get() != NULL)
154 m_options_ap->GetThreadSpec()->SetIndex(index);
155 }
156 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
157
158}
159
160uint32_t
161BreakpointLocation::GetThreadIndex() const
162{
163 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
164 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
165 else
166 return 0;
167}
168
169void
170BreakpointLocation::SetThreadName (const char *thread_name)
171{
172 if (thread_name != NULL)
173 GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
174 else
175 {
176 // If we're resetting this to an invalid thread id, then
177 // don't make an options pointer just to do that.
178 if (m_options_ap.get() != NULL)
179 m_options_ap->GetThreadSpec()->SetName(thread_name);
180 }
181 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
182}
183
184const char *
185BreakpointLocation::GetThreadName () const
186{
187 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
188 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
189 else
190 return NULL;
191}
192
193void
194BreakpointLocation::SetQueueName (const char *queue_name)
195{
196 if (queue_name != NULL)
197 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
198 else
199 {
200 // If we're resetting this to an invalid thread id, then
201 // don't make an options pointer just to do that.
202 if (m_options_ap.get() != NULL)
203 m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
204 }
205 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
206}
207
208const char *
209BreakpointLocation::GetQueueName () const
210{
211 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
212 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
213 else
214 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000215}
216
217bool
218BreakpointLocation::InvokeCallback (StoppointCallbackContext *context)
219{
Jim Ingham01363092010-06-18 01:00:58 +0000220 if (m_options_ap.get() != NULL && m_options_ap->HasCallback())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000221 return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID());
Jim Ingham01363092010-06-18 01:00:58 +0000222 else
223 return m_owner.InvokeCallback (context, GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000224}
225
226void
227BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton,
228 bool is_synchronous)
229{
230 // The default "Baton" class will keep a copy of "baton" and won't free
231 // or delete it when it goes goes out of scope.
232 GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000233 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000234}
235
236void
237BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp,
238 bool is_synchronous)
239{
240 GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000241 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000242}
243
Jim Ingham36f3b362010-10-14 23:45:03 +0000244
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000245void
246BreakpointLocation::ClearCallback ()
247{
248 GetLocationOptions()->ClearCallback();
249}
250
Jim Ingham36f3b362010-10-14 23:45:03 +0000251void
252BreakpointLocation::SetCondition (const char *condition)
253{
254 GetLocationOptions()->SetCondition (condition);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000255 SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged);
Jim Ingham36f3b362010-10-14 23:45:03 +0000256}
257
Jim Ingham36f3b362010-10-14 23:45:03 +0000258const char *
Sean Callanan3dbf3462013-04-19 07:09:15 +0000259BreakpointLocation::GetConditionText (size_t *hash) const
Jim Ingham36f3b362010-10-14 23:45:03 +0000260{
Sean Callanan3dbf3462013-04-19 07:09:15 +0000261 return GetOptionsNoCreate()->GetConditionText(hash);
262}
263
264bool
265BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
266{
267 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Sean Callananb4987e32013-06-06 20:18:50 +0000268
269 Mutex::Locker evaluation_locker(m_condition_mutex);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000270
271 size_t condition_hash;
272 const char *condition_text = GetConditionText(&condition_hash);
273
274 if (!condition_text)
Sean Callananec537a22013-05-10 21:58:45 +0000275 {
276 m_user_expression_sp.reset();
Sean Callanan3dbf3462013-04-19 07:09:15 +0000277 return false;
Sean Callananec537a22013-05-10 21:58:45 +0000278 }
Sean Callanan3dbf3462013-04-19 07:09:15 +0000279
280 if (condition_hash != m_condition_hash ||
281 !m_user_expression_sp ||
282 !m_user_expression_sp->MatchesContext(exe_ctx))
283 {
284 m_user_expression_sp.reset(new ClangUserExpression(condition_text,
285 NULL,
286 lldb::eLanguageTypeUnknown,
287 ClangUserExpression::eResultTypeAny));
288
289 StreamString errors;
290
291 if (!m_user_expression_sp->Parse(errors,
292 exe_ctx,
293 eExecutionPolicyOnlyWhenNeeded,
Greg Clayton23f8c952014-03-24 23:10:19 +0000294 true,
295 false))
Sean Callanan3dbf3462013-04-19 07:09:15 +0000296 {
297 error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s",
298 errors.GetData());
299 m_user_expression_sp.reset();
300 return false;
301 }
302
303 m_condition_hash = condition_hash;
304 }
305
306 // We need to make sure the user sees any parse errors in their condition, so we'll hook the
307 // constructor errors up to the debugger's Async I/O.
308
309 ValueObjectSP result_value_sp;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000310
311 EvaluateExpressionOptions options;
312 options.SetUnwindOnError(true);
313 options.SetIgnoreBreakpoints(true);
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000314 options.SetTryAllThreads(true);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000315
316 Error expr_error;
317
318 StreamString execution_errors;
319
320 ClangExpressionVariableSP result_variable_sp;
321
Jim Ingham1624a2d2014-05-05 02:26:40 +0000322 ExpressionResults result_code =
Sean Callanan3dbf3462013-04-19 07:09:15 +0000323 m_user_expression_sp->Execute(execution_errors,
324 exe_ctx,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000325 options,
Sean Callanan3dbf3462013-04-19 07:09:15 +0000326 m_user_expression_sp,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000327 result_variable_sp);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000328
329 bool ret;
330
Jim Ingham8646d3c2014-05-05 02:47:44 +0000331 if (result_code == eExpressionCompleted)
Sean Callanan3dbf3462013-04-19 07:09:15 +0000332 {
Sean Callanan467441d52013-05-29 20:22:18 +0000333 if (!result_variable_sp)
334 {
Sean Callanan467441d52013-05-29 20:22:18 +0000335 error.SetErrorString("Expression did not return a result");
Sean Callanan879425f2013-06-24 17:58:46 +0000336 return false;
Sean Callanan467441d52013-05-29 20:22:18 +0000337 }
338
Sean Callanan3dbf3462013-04-19 07:09:15 +0000339 result_value_sp = result_variable_sp->GetValueObject();
340
341 if (result_value_sp)
342 {
343 Scalar scalar_value;
344 if (result_value_sp->ResolveValue (scalar_value))
345 {
346 if (scalar_value.ULongLong(1) == 0)
347 ret = false;
348 else
349 ret = true;
350 if (log)
351 log->Printf("Condition successfully evaluated, result is %s.\n",
352 ret ? "true" : "false");
353 }
354 else
355 {
356 ret = false;
357 error.SetErrorString("Failed to get an integer result from the expression");
358 }
359 }
360 else
361 {
362 ret = false;
363 error.SetErrorString("Failed to get any result from the expression");
364 }
365 }
366 else
367 {
368 ret = false;
369 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData());
370 }
371
372 return ret;
Jim Ingham36f3b362010-10-14 23:45:03 +0000373}
374
Greg Claytonc982c762010-07-09 20:39:50 +0000375uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000376BreakpointLocation::GetIgnoreCount ()
377{
Jim Ingham05407f62010-06-22 21:12:54 +0000378 return GetOptionsNoCreate()->GetIgnoreCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000379}
380
381void
Greg Claytonc982c762010-07-09 20:39:50 +0000382BreakpointLocation::SetIgnoreCount (uint32_t n)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000383{
384 GetLocationOptions()->SetIgnoreCount(n);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000385 SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000386}
387
Jim Ingham0fd1b752012-06-26 22:27:55 +0000388void
389BreakpointLocation::DecrementIgnoreCount()
390{
391 if (m_options_ap.get() != NULL)
392 {
393 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
394 if (loc_ignore != 0)
395 m_options_ap->SetIgnoreCount(loc_ignore - 1);
396 }
397}
398
399bool
400BreakpointLocation::IgnoreCountShouldStop()
401{
402 if (m_options_ap.get() != NULL)
403 {
404 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
405 if (loc_ignore != 0)
406 {
407 m_owner.DecrementIgnoreCount();
408 DecrementIgnoreCount(); // Have to decrement our owners' ignore count, since it won't get a
409 // chance to.
410 return false;
411 }
412 }
413 return true;
414}
415
Jim Ingham1b54c882010-06-16 02:00:15 +0000416const BreakpointOptions *
Jim Ingham05407f62010-06-22 21:12:54 +0000417BreakpointLocation::GetOptionsNoCreate () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000418{
419 if (m_options_ap.get() != NULL)
420 return m_options_ap.get();
421 else
422 return m_owner.GetOptions ();
423}
424
425BreakpointOptions *
426BreakpointLocation::GetLocationOptions ()
427{
Jim Ingham01363092010-06-18 01:00:58 +0000428 // If we make the copy we don't copy the callbacks because that is potentially
429 // expensive and we don't want to do that for the simple case where someone is
430 // just disabling the location.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000431 if (m_options_ap.get() == NULL)
Jim Ingham01363092010-06-18 01:00:58 +0000432 m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ()));
433
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000434 return m_options_ap.get();
435}
436
Jim Ingham1b54c882010-06-16 02:00:15 +0000437bool
438BreakpointLocation::ValidForThisThread (Thread *thread)
439{
Jim Ingham05407f62010-06-22 21:12:54 +0000440 return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
Jim Ingham1b54c882010-06-16 02:00:15 +0000441}
442
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000443// RETURNS - true if we should stop at this breakpoint, false if we
Jim Ingham1b54c882010-06-16 02:00:15 +0000444// should continue. Note, we don't check the thread spec for the breakpoint
445// here, since if the breakpoint is not for this thread, then the event won't
446// even get reported, so the check is redundant.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000447
448bool
449BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
450{
451 bool should_stop = true;
Greg Clayton5160ce52013-03-27 23:08:40 +0000452 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000453
Jim Inghama672ece2014-10-22 01:54:17 +0000454 // Do this first, if a location is disabled, it shouldn't increment its hit count.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000455 if (!IsEnabled())
456 return false;
457
Jim Ingham0fd1b752012-06-26 22:27:55 +0000458 if (!IgnoreCountShouldStop())
459 return false;
460
461 if (!m_owner.IgnoreCountShouldStop())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000462 return false;
463
Jim Ingham36f3b362010-10-14 23:45:03 +0000464 // We only run synchronous callbacks in ShouldStop:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000465 context->is_synchronous = true;
466 should_stop = InvokeCallback (context);
Jim Ingham36f3b362010-10-14 23:45:03 +0000467
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000468 if (log)
Jim Ingham36f3b362010-10-14 23:45:03 +0000469 {
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000470 StreamString s;
471 GetDescription (&s, lldb::eDescriptionLevelVerbose);
472 log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000473 }
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000474
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000475 return should_stop;
476}
477
Jim Inghama672ece2014-10-22 01:54:17 +0000478void
479BreakpointLocation::BumpHitCount()
480{
481 if (IsEnabled())
Jim Inghamd762df82015-01-15 01:41:04 +0000482 {
483 // Step our hit count, and also step the hit count of the owner.
Jim Inghama672ece2014-10-22 01:54:17 +0000484 IncrementHitCount();
Jim Inghamd762df82015-01-15 01:41:04 +0000485 m_owner.IncrementHitCount();
486 }
487}
488
489void
490BreakpointLocation::UndoBumpHitCount()
491{
492 if (IsEnabled())
493 {
494 // Step our hit count, and also step the hit count of the owner.
495 DecrementHitCount();
496 m_owner.DecrementHitCount();
497 }
Jim Inghama672ece2014-10-22 01:54:17 +0000498}
499
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000500bool
501BreakpointLocation::IsResolved () const
502{
503 return m_bp_site_sp.get() != NULL;
504}
505
Jim Ingham36f3b362010-10-14 23:45:03 +0000506lldb::BreakpointSiteSP
507BreakpointLocation::GetBreakpointSite() const
508{
509 return m_bp_site_sp;
510}
511
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000512bool
513BreakpointLocation::ResolveBreakpointSite ()
514{
515 if (m_bp_site_sp)
516 return true;
517
Greg Claytonf5e56de2010-09-14 23:36:40 +0000518 Process *process = m_owner.GetTarget().GetProcessSP().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000519 if (process == NULL)
520 return false;
521
Greg Claytoneb023e72013-10-11 19:48:25 +0000522 lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), m_owner.IsHardware());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000523
Stephen Wilson50bd94f2010-07-17 00:56:13 +0000524 if (new_id == LLDB_INVALID_BREAK_ID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000525 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000526 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000527 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000528 log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n",
Greg Claytonf3ef3d22011-05-22 22:46:53 +0000529 m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000530 return false;
531 }
532
533 return true;
534}
535
536bool
537BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp)
538{
539 m_bp_site_sp = bp_site_sp;
540 return true;
541}
542
543bool
544BreakpointLocation::ClearBreakpointSite ()
545{
546 if (m_bp_site_sp.get())
547 {
Jim Ingham15783132014-03-12 22:03:13 +0000548 ProcessSP process_sp(m_owner.GetTarget().GetProcessSP());
549 // If the process exists, get it to remove the owner, it will remove the physical implementation
550 // of the breakpoint as well if there are no more owners. Otherwise just remove this owner.
551 if (process_sp)
552 process_sp->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(),
Jim Ingham01363092010-06-18 01:00:58 +0000553 GetID(), m_bp_site_sp);
Jim Ingham15783132014-03-12 22:03:13 +0000554 else
555 m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID());
556
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000557 m_bp_site_sp.reset();
558 return true;
559 }
560 return false;
561}
562
563void
564BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
565{
566 SymbolContext sc;
Jim Ingham1391cc72012-09-22 00:04:04 +0000567
568 // If the description level is "initial" then the breakpoint is printing out our initial state,
569 // and we should let it decide how it wants to print our label.
570 if (level != eDescriptionLevelInitial)
571 {
572 s->Indent();
573 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
574 }
575
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000576 if (level == lldb::eDescriptionLevelBrief)
577 return;
578
Jim Ingham1391cc72012-09-22 00:04:04 +0000579 if (level != eDescriptionLevelInitial)
580 s->PutCString(": ");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000581
582 if (level == lldb::eDescriptionLevelVerbose)
583 s->IndentMore();
584
585 if (m_address.IsSectionOffset())
586 {
587 m_address.CalculateSymbolContext(&sc);
588
Jim Ingham1391cc72012-09-22 00:04:04 +0000589 if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000590 {
Jim Ingham1460e4b2014-01-10 23:46:59 +0000591 if (IsReExported())
592 s->PutCString ("re-exported target = ");
593 else
594 s->PutCString("where = ");
Jason Molendac980fa92015-02-13 23:24:21 +0000595 sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false, true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000596 }
597 else
598 {
599 if (sc.module_sp)
600 {
601 s->EOL();
602 s->Indent("module = ");
603 sc.module_sp->GetFileSpec().Dump (s);
604 }
605
606 if (sc.comp_unit != NULL)
607 {
608 s->EOL();
609 s->Indent("compile unit = ");
Jim Ingham517b3b22010-10-27 22:58:34 +0000610 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000611
612 if (sc.function != NULL)
613 {
614 s->EOL();
615 s->Indent("function = ");
616 s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>"));
617 }
618
619 if (sc.line_entry.line > 0)
620 {
621 s->EOL();
622 s->Indent("location = ");
Greg Clayton6dadd502010-09-02 21:44:10 +0000623 sc.line_entry.DumpStopContext (s, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000624 }
625
626 }
627 else
628 {
629 // If we don't have a comp unit, see if we have a symbol we can print.
630 if (sc.symbol)
631 {
632 s->EOL();
Jim Ingham1460e4b2014-01-10 23:46:59 +0000633 if (IsReExported())
634 s->Indent ("re-exported target = ");
635 else
636 s->Indent("symbol = ");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000637 s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>"));
638 }
639 }
640 }
641 }
642
643 if (level == lldb::eDescriptionLevelVerbose)
644 {
645 s->EOL();
646 s->Indent();
647 }
Jim Ingham1391cc72012-09-22 00:04:04 +0000648
649 if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
650 s->Printf (", ");
651 s->Printf ("address = ");
652
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000653 ExecutionContextScope *exe_scope = NULL;
654 Target *target = &m_owner.GetTarget();
655 if (target)
656 exe_scope = target->GetProcessSP().get();
657 if (exe_scope == NULL)
658 exe_scope = target;
659
Jim Ingham8f632662014-03-04 03:09:00 +0000660 if (level == eDescriptionLevelInitial)
Jim Ingham1391cc72012-09-22 00:04:04 +0000661 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
662 else
663 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
Jim Ingham1460e4b2014-01-10 23:46:59 +0000664
665 if (IsIndirect() && m_bp_site_sp)
666 {
667 Address resolved_address;
668 resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
669 Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
670 if (resolved_symbol)
671 {
672 if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
673 s->Printf (", ");
674 else if (level == lldb::eDescriptionLevelVerbose)
675 {
676 s->EOL();
677 s->Indent();
678 }
679 s->Printf ("indirect target = %s", resolved_symbol->GetName().GetCString());
680 }
681 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000682
683 if (level == lldb::eDescriptionLevelVerbose)
684 {
685 s->EOL();
686 s->Indent();
687 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
688
689 s->Indent();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000690 s->Printf ("hit count = %-4u\n", GetHitCount());
691
692 if (m_options_ap.get())
693 {
Jim Ingham01363092010-06-18 01:00:58 +0000694 s->Indent();
695 m_options_ap->GetDescription (s, level);
696 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000697 }
698 s->IndentLess();
699 }
Jim Ingham1391cc72012-09-22 00:04:04 +0000700 else if (level != eDescriptionLevelInitial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000701 {
Jim Ingham01363092010-06-18 01:00:58 +0000702 s->Printf(", %sresolved, hit count = %u ",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000703 (IsResolved() ? "" : "un"),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000704 GetHitCount());
Jim Ingham01363092010-06-18 01:00:58 +0000705 if (m_options_ap.get())
706 {
707 m_options_ap->GetDescription (s, level);
708 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000709 }
710}
711
712void
713BreakpointLocation::Dump(Stream *s) const
714{
715 if (s == NULL)
716 return;
717
Daniel Malead01b2952012-11-29 21:49:15 +0000718 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 +0000719 "hw_index = %i hit_count = %-4u ignore_count = %-4u",
Johnny Chen9ec3c4f2012-01-26 00:08:14 +0000720 GetID(),
721 GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
722 (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()),
Johnny Chen50df1f92012-01-30 22:48:10 +0000723 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled",
Johnny Chen9ec3c4f2012-01-26 00:08:14 +0000724 IsHardware() ? "hardware" : "software",
725 GetHardwareIndex(),
726 GetHitCount(),
727 GetOptionsNoCreate()->GetIgnoreCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000728}
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000729
730void
731BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind)
732{
733 if (!m_being_created
734 && !m_owner.IsInternal()
735 && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
736 {
737 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind,
738 m_owner.shared_from_this());
739 data->GetBreakpointLocationCollection().Add (shared_from_this());
740 m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
741 }
742}
Jim Ingham77fd7382014-09-10 21:40:47 +0000743
744void
745BreakpointLocation::SwapLocation (BreakpointLocationSP swap_from)
746{
747 m_address = swap_from->m_address;
748 m_should_resolve_indirect_functions = swap_from->m_should_resolve_indirect_functions;
749 m_is_reexported = swap_from->m_is_reexported;
750 m_is_indirect = swap_from->m_is_indirect;
751 m_user_expression_sp.reset();
752}