blob: d691405862dcf16165977159cea045746e77c283 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- BreakpointLocation.cpp ----------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
11// C++ Includes
12#include <string>
13
14// Other libraries and framework includes
15// Project includes
16#include "lldb/Breakpoint/BreakpointLocation.h"
17#include "lldb/Breakpoint/BreakpointID.h"
18#include "lldb/Breakpoint/StoppointCallbackContext.h"
Jim Ingham5b52f0c2011-06-02 23:58:26 +000019#include "lldb/Core/Debugger.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020#include "lldb/Core/Log.h"
Greg Clayton1f746072012-08-29 21:13:06 +000021#include "lldb/Core/Module.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Core/StreamString.h"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000023#include "lldb/Core/ValueObject.h"
Bruce Mitchener937e3962015-09-21 16:56:08 +000024#include "lldb/Expression/ExpressionVariable.h"
Jim Ingham151c0322015-09-15 21:13:50 +000025#include "lldb/Expression/UserExpression.h"
Greg Clayton1f746072012-08-29 21:13:06 +000026#include "lldb/Symbol/CompileUnit.h"
27#include "lldb/Symbol/Symbol.h"
Jim Ingham151c0322015-09-15 21:13:50 +000028#include "lldb/Symbol/TypeSystem.h"
Greg Clayton1f746072012-08-29 21:13:06 +000029#include "lldb/Target/Target.h"
30#include "lldb/Target/Process.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Target/Thread.h"
Jim Ingham1b54c882010-06-16 02:00:15 +000032#include "lldb/Target/ThreadSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033
34using namespace lldb;
35using namespace lldb_private;
36
37BreakpointLocation::BreakpointLocation
38(
39 break_id_t loc_id,
40 Breakpoint &owner,
Greg Claytonc0d34462011-02-05 00:38:04 +000041 const Address &addr,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042 lldb::tid_t tid,
Jim Ingham1460e4b2014-01-10 23:46:59 +000043 bool hardware,
44 bool check_for_resolver
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045) :
Greg Claytonf3ef3d22011-05-22 22:46:53 +000046 StoppointLocation (loc_id, addr.GetOpcodeLoadAddress(&owner.GetTarget()), hardware),
Jim Inghame6bc6cb2012-02-08 05:23:15 +000047 m_being_created(true),
Jim Ingham1460e4b2014-01-10 23:46:59 +000048 m_should_resolve_indirect_functions (false),
49 m_is_reexported (false),
50 m_is_indirect (false),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000051 m_address (addr),
52 m_owner (owner),
53 m_options_ap (),
Sean Callananb4987e32013-06-06 20:18:50 +000054 m_bp_site_sp (),
55 m_condition_mutex ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056{
Jim Ingham1460e4b2014-01-10 23:46:59 +000057 if (check_for_resolver)
58 {
59 Symbol *symbol = m_address.CalculateSymbolContextSymbol();
60 if (symbol && symbol->IsIndirect())
61 {
62 SetShouldResolveIndirectFunctions (true);
63 }
64 }
65
Jim Ingham1b54c882010-06-16 02:00:15 +000066 SetThreadID (tid);
Jim Inghame6bc6cb2012-02-08 05:23:15 +000067 m_being_created = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000068}
69
70BreakpointLocation::~BreakpointLocation()
71{
72 ClearBreakpointSite();
73}
74
75lldb::addr_t
Greg Clayton13238c42010-06-14 04:18:27 +000076BreakpointLocation::GetLoadAddress () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077{
Greg Claytonf3ef3d22011-05-22 22:46:53 +000078 return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000079}
80
81Address &
82BreakpointLocation::GetAddress ()
83{
84 return m_address;
85}
86
87Breakpoint &
88BreakpointLocation::GetBreakpoint ()
89{
90 return m_owner;
91}
92
Jim Ingham151c0322015-09-15 21:13:50 +000093Target &
94BreakpointLocation::GetTarget()
95{
96 return m_owner.GetTarget();
97}
98
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099bool
Johnny Chenfdad6792012-02-01 19:05:20 +0000100BreakpointLocation::IsEnabled () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000101{
Johnny Chen50df1f92012-01-30 22:48:10 +0000102 if (!m_owner.IsEnabled())
103 return false;
104 else if (m_options_ap.get() != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000105 return m_options_ap->IsEnabled();
106 else
Johnny Chen50df1f92012-01-30 22:48:10 +0000107 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000108}
109
110void
111BreakpointLocation::SetEnabled (bool enabled)
112{
113 GetLocationOptions()->SetEnabled(enabled);
114 if (enabled)
115 {
116 ResolveBreakpointSite();
117 }
118 else
119 {
120 ClearBreakpointSite();
121 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000122 SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000123}
124
125void
126BreakpointLocation::SetThreadID (lldb::tid_t thread_id)
127{
Jim Ingham1b54c882010-06-16 02:00:15 +0000128 if (thread_id != LLDB_INVALID_THREAD_ID)
129 GetLocationOptions()->SetThreadID(thread_id);
130 else
131 {
132 // If we're resetting this to an invalid thread id, then
133 // don't make an options pointer just to do that.
134 if (m_options_ap.get() != NULL)
135 m_options_ap->SetThreadID (thread_id);
136 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000137 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
138}
139
140lldb::tid_t
141BreakpointLocation::GetThreadID ()
142{
143 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
144 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
145 else
146 return LLDB_INVALID_THREAD_ID;
147}
148
149void
150BreakpointLocation::SetThreadIndex (uint32_t index)
151{
152 if (index != 0)
153 GetLocationOptions()->GetThreadSpec()->SetIndex(index);
154 else
155 {
156 // If we're resetting this to an invalid thread id, then
157 // don't make an options pointer just to do that.
158 if (m_options_ap.get() != NULL)
159 m_options_ap->GetThreadSpec()->SetIndex(index);
160 }
161 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
162
163}
164
165uint32_t
166BreakpointLocation::GetThreadIndex() const
167{
168 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
169 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
170 else
171 return 0;
172}
173
174void
175BreakpointLocation::SetThreadName (const char *thread_name)
176{
177 if (thread_name != NULL)
178 GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
179 else
180 {
181 // If we're resetting this to an invalid thread id, then
182 // don't make an options pointer just to do that.
183 if (m_options_ap.get() != NULL)
184 m_options_ap->GetThreadSpec()->SetName(thread_name);
185 }
186 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
187}
188
189const char *
190BreakpointLocation::GetThreadName () const
191{
192 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
193 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
194 else
195 return NULL;
196}
197
198void
199BreakpointLocation::SetQueueName (const char *queue_name)
200{
201 if (queue_name != NULL)
202 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
203 else
204 {
205 // If we're resetting this to an invalid thread id, then
206 // don't make an options pointer just to do that.
207 if (m_options_ap.get() != NULL)
208 m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
209 }
210 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
211}
212
213const char *
214BreakpointLocation::GetQueueName () const
215{
216 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
217 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
218 else
219 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000220}
221
222bool
223BreakpointLocation::InvokeCallback (StoppointCallbackContext *context)
224{
Jim Ingham01363092010-06-18 01:00:58 +0000225 if (m_options_ap.get() != NULL && m_options_ap->HasCallback())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000226 return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID());
Jim Ingham01363092010-06-18 01:00:58 +0000227 else
228 return m_owner.InvokeCallback (context, GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000229}
230
231void
232BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton,
233 bool is_synchronous)
234{
235 // The default "Baton" class will keep a copy of "baton" and won't free
236 // or delete it when it goes goes out of scope.
237 GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000238 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000239}
240
241void
242BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp,
243 bool is_synchronous)
244{
245 GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000246 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000247}
248
Jim Ingham36f3b362010-10-14 23:45:03 +0000249
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000250void
251BreakpointLocation::ClearCallback ()
252{
253 GetLocationOptions()->ClearCallback();
254}
255
Jim Ingham36f3b362010-10-14 23:45:03 +0000256void
257BreakpointLocation::SetCondition (const char *condition)
258{
259 GetLocationOptions()->SetCondition (condition);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000260 SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged);
Jim Ingham36f3b362010-10-14 23:45:03 +0000261}
262
Jim Ingham36f3b362010-10-14 23:45:03 +0000263const char *
Sean Callanan3dbf3462013-04-19 07:09:15 +0000264BreakpointLocation::GetConditionText (size_t *hash) const
Jim Ingham36f3b362010-10-14 23:45:03 +0000265{
Sean Callanan3dbf3462013-04-19 07:09:15 +0000266 return GetOptionsNoCreate()->GetConditionText(hash);
267}
268
269bool
270BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
271{
272 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Sean Callananb4987e32013-06-06 20:18:50 +0000273
274 Mutex::Locker evaluation_locker(m_condition_mutex);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000275
276 size_t condition_hash;
277 const char *condition_text = GetConditionText(&condition_hash);
278
279 if (!condition_text)
Sean Callananec537a22013-05-10 21:58:45 +0000280 {
281 m_user_expression_sp.reset();
Sean Callanan3dbf3462013-04-19 07:09:15 +0000282 return false;
Sean Callananec537a22013-05-10 21:58:45 +0000283 }
Sean Callanan3dbf3462013-04-19 07:09:15 +0000284
285 if (condition_hash != m_condition_hash ||
286 !m_user_expression_sp ||
287 !m_user_expression_sp->MatchesContext(exe_ctx))
288 {
Jim Ingham151c0322015-09-15 21:13:50 +0000289 LanguageType language = eLanguageTypeUnknown;
290 // See if we can figure out the language from the frame, otherwise use the default language:
291 CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit();
292 if (comp_unit)
293 language = comp_unit->GetLanguage();
294
295 Error error;
296 m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(condition_text,
297 NULL,
298 language,
299 Expression::eResultTypeAny,
300 error));
301 if (error.Fail())
302 {
303 if (log)
304 log->Printf("Error getting condition expression: %s.", error.AsCString());
305 m_user_expression_sp.reset();
306 return true;
307 }
308
Sean Callanan3dbf3462013-04-19 07:09:15 +0000309
310 StreamString errors;
311
312 if (!m_user_expression_sp->Parse(errors,
313 exe_ctx,
314 eExecutionPolicyOnlyWhenNeeded,
Greg Clayton23f8c952014-03-24 23:10:19 +0000315 true,
316 false))
Sean Callanan3dbf3462013-04-19 07:09:15 +0000317 {
318 error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s",
319 errors.GetData());
320 m_user_expression_sp.reset();
321 return false;
322 }
323
324 m_condition_hash = condition_hash;
325 }
326
327 // We need to make sure the user sees any parse errors in their condition, so we'll hook the
328 // constructor errors up to the debugger's Async I/O.
329
330 ValueObjectSP result_value_sp;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000331
332 EvaluateExpressionOptions options;
333 options.SetUnwindOnError(true);
334 options.SetIgnoreBreakpoints(true);
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000335 options.SetTryAllThreads(true);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000336
337 Error expr_error;
338
339 StreamString execution_errors;
340
Sean Callananbc8ac342015-09-04 20:49:51 +0000341 ExpressionVariableSP result_variable_sp;
Sean Callanan3dbf3462013-04-19 07:09:15 +0000342
Jim Ingham1624a2d2014-05-05 02:26:40 +0000343 ExpressionResults result_code =
Sean Callanan3dbf3462013-04-19 07:09:15 +0000344 m_user_expression_sp->Execute(execution_errors,
345 exe_ctx,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000346 options,
Sean Callanan3dbf3462013-04-19 07:09:15 +0000347 m_user_expression_sp,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000348 result_variable_sp);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000349
350 bool ret;
351
Jim Ingham8646d3c2014-05-05 02:47:44 +0000352 if (result_code == eExpressionCompleted)
Sean Callanan3dbf3462013-04-19 07:09:15 +0000353 {
Sean Callanan467441d52013-05-29 20:22:18 +0000354 if (!result_variable_sp)
355 {
Sean Callanan467441d52013-05-29 20:22:18 +0000356 error.SetErrorString("Expression did not return a result");
Sean Callanan879425f2013-06-24 17:58:46 +0000357 return false;
Sean Callanan467441d52013-05-29 20:22:18 +0000358 }
359
Sean Callanan3dbf3462013-04-19 07:09:15 +0000360 result_value_sp = result_variable_sp->GetValueObject();
361
362 if (result_value_sp)
363 {
364 Scalar scalar_value;
365 if (result_value_sp->ResolveValue (scalar_value))
366 {
367 if (scalar_value.ULongLong(1) == 0)
368 ret = false;
369 else
370 ret = true;
371 if (log)
372 log->Printf("Condition successfully evaluated, result is %s.\n",
373 ret ? "true" : "false");
374 }
375 else
376 {
377 ret = false;
378 error.SetErrorString("Failed to get an integer result from the expression");
379 }
380 }
381 else
382 {
383 ret = false;
384 error.SetErrorString("Failed to get any result from the expression");
385 }
386 }
387 else
388 {
389 ret = false;
390 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData());
391 }
392
393 return ret;
Jim Ingham36f3b362010-10-14 23:45:03 +0000394}
395
Greg Claytonc982c762010-07-09 20:39:50 +0000396uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000397BreakpointLocation::GetIgnoreCount ()
398{
Jim Ingham05407f62010-06-22 21:12:54 +0000399 return GetOptionsNoCreate()->GetIgnoreCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000400}
401
402void
Greg Claytonc982c762010-07-09 20:39:50 +0000403BreakpointLocation::SetIgnoreCount (uint32_t n)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000404{
405 GetLocationOptions()->SetIgnoreCount(n);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000406 SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000407}
408
Jim Ingham0fd1b752012-06-26 22:27:55 +0000409void
410BreakpointLocation::DecrementIgnoreCount()
411{
412 if (m_options_ap.get() != NULL)
413 {
414 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
415 if (loc_ignore != 0)
416 m_options_ap->SetIgnoreCount(loc_ignore - 1);
417 }
418}
419
420bool
421BreakpointLocation::IgnoreCountShouldStop()
422{
423 if (m_options_ap.get() != NULL)
424 {
425 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
426 if (loc_ignore != 0)
427 {
428 m_owner.DecrementIgnoreCount();
429 DecrementIgnoreCount(); // Have to decrement our owners' ignore count, since it won't get a
430 // chance to.
431 return false;
432 }
433 }
434 return true;
435}
436
Jim Ingham1b54c882010-06-16 02:00:15 +0000437const BreakpointOptions *
Jim Ingham05407f62010-06-22 21:12:54 +0000438BreakpointLocation::GetOptionsNoCreate () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000439{
440 if (m_options_ap.get() != NULL)
441 return m_options_ap.get();
442 else
443 return m_owner.GetOptions ();
444}
445
446BreakpointOptions *
447BreakpointLocation::GetLocationOptions ()
448{
Jim Ingham01363092010-06-18 01:00:58 +0000449 // If we make the copy we don't copy the callbacks because that is potentially
450 // expensive and we don't want to do that for the simple case where someone is
451 // just disabling the location.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000452 if (m_options_ap.get() == NULL)
Jim Ingham01363092010-06-18 01:00:58 +0000453 m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ()));
454
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000455 return m_options_ap.get();
456}
457
Jim Ingham1b54c882010-06-16 02:00:15 +0000458bool
459BreakpointLocation::ValidForThisThread (Thread *thread)
460{
Jim Ingham05407f62010-06-22 21:12:54 +0000461 return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
Jim Ingham1b54c882010-06-16 02:00:15 +0000462}
463
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000464// RETURNS - true if we should stop at this breakpoint, false if we
Jim Ingham1b54c882010-06-16 02:00:15 +0000465// should continue. Note, we don't check the thread spec for the breakpoint
466// here, since if the breakpoint is not for this thread, then the event won't
467// even get reported, so the check is redundant.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000468
469bool
470BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
471{
472 bool should_stop = true;
Greg Clayton5160ce52013-03-27 23:08:40 +0000473 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000474
Jim Inghama672ece2014-10-22 01:54:17 +0000475 // Do this first, if a location is disabled, it shouldn't increment its hit count.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000476 if (!IsEnabled())
477 return false;
478
Jim Ingham0fd1b752012-06-26 22:27:55 +0000479 if (!IgnoreCountShouldStop())
480 return false;
481
482 if (!m_owner.IgnoreCountShouldStop())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000483 return false;
484
Jim Ingham36f3b362010-10-14 23:45:03 +0000485 // We only run synchronous callbacks in ShouldStop:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000486 context->is_synchronous = true;
487 should_stop = InvokeCallback (context);
Jim Ingham36f3b362010-10-14 23:45:03 +0000488
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000489 if (log)
Jim Ingham36f3b362010-10-14 23:45:03 +0000490 {
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000491 StreamString s;
492 GetDescription (&s, lldb::eDescriptionLevelVerbose);
493 log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000494 }
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000495
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000496 return should_stop;
497}
498
Jim Inghama672ece2014-10-22 01:54:17 +0000499void
500BreakpointLocation::BumpHitCount()
501{
502 if (IsEnabled())
Jim Inghamd762df82015-01-15 01:41:04 +0000503 {
504 // Step our hit count, and also step the hit count of the owner.
Jim Inghama672ece2014-10-22 01:54:17 +0000505 IncrementHitCount();
Jim Inghamd762df82015-01-15 01:41:04 +0000506 m_owner.IncrementHitCount();
507 }
508}
509
510void
511BreakpointLocation::UndoBumpHitCount()
512{
513 if (IsEnabled())
514 {
515 // Step our hit count, and also step the hit count of the owner.
516 DecrementHitCount();
517 m_owner.DecrementHitCount();
518 }
Jim Inghama672ece2014-10-22 01:54:17 +0000519}
520
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000521bool
522BreakpointLocation::IsResolved () const
523{
524 return m_bp_site_sp.get() != NULL;
525}
526
Jim Ingham36f3b362010-10-14 23:45:03 +0000527lldb::BreakpointSiteSP
528BreakpointLocation::GetBreakpointSite() const
529{
530 return m_bp_site_sp;
531}
532
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000533bool
534BreakpointLocation::ResolveBreakpointSite ()
535{
536 if (m_bp_site_sp)
537 return true;
538
Greg Claytonf5e56de2010-09-14 23:36:40 +0000539 Process *process = m_owner.GetTarget().GetProcessSP().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000540 if (process == NULL)
541 return false;
542
Greg Claytoneb023e72013-10-11 19:48:25 +0000543 lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), m_owner.IsHardware());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000544
Stephen Wilson50bd94f2010-07-17 00:56:13 +0000545 if (new_id == LLDB_INVALID_BREAK_ID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000546 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000547 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000548 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000549 log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n",
Greg Claytonf3ef3d22011-05-22 22:46:53 +0000550 m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000551 return false;
552 }
553
554 return true;
555}
556
557bool
558BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp)
559{
560 m_bp_site_sp = bp_site_sp;
Ilia K9b618d22015-04-09 12:55:13 +0000561 SendBreakpointLocationChangedEvent (eBreakpointEventTypeLocationsResolved);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000562 return true;
563}
564
565bool
566BreakpointLocation::ClearBreakpointSite ()
567{
568 if (m_bp_site_sp.get())
569 {
Jim Ingham15783132014-03-12 22:03:13 +0000570 ProcessSP process_sp(m_owner.GetTarget().GetProcessSP());
571 // If the process exists, get it to remove the owner, it will remove the physical implementation
572 // of the breakpoint as well if there are no more owners. Otherwise just remove this owner.
573 if (process_sp)
574 process_sp->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(),
Jim Ingham01363092010-06-18 01:00:58 +0000575 GetID(), m_bp_site_sp);
Jim Ingham15783132014-03-12 22:03:13 +0000576 else
577 m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID());
578
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000579 m_bp_site_sp.reset();
580 return true;
581 }
582 return false;
583}
584
585void
586BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
587{
588 SymbolContext sc;
Jim Ingham1391cc72012-09-22 00:04:04 +0000589
590 // If the description level is "initial" then the breakpoint is printing out our initial state,
591 // and we should let it decide how it wants to print our label.
592 if (level != eDescriptionLevelInitial)
593 {
594 s->Indent();
595 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
596 }
597
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000598 if (level == lldb::eDescriptionLevelBrief)
599 return;
600
Jim Ingham1391cc72012-09-22 00:04:04 +0000601 if (level != eDescriptionLevelInitial)
602 s->PutCString(": ");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000603
604 if (level == lldb::eDescriptionLevelVerbose)
605 s->IndentMore();
606
607 if (m_address.IsSectionOffset())
608 {
609 m_address.CalculateSymbolContext(&sc);
610
Jim Ingham1391cc72012-09-22 00:04:04 +0000611 if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000612 {
Jim Ingham1460e4b2014-01-10 23:46:59 +0000613 if (IsReExported())
614 s->PutCString ("re-exported target = ");
615 else
616 s->PutCString("where = ");
Jason Molendac980fa92015-02-13 23:24:21 +0000617 sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false, true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000618 }
619 else
620 {
621 if (sc.module_sp)
622 {
623 s->EOL();
624 s->Indent("module = ");
625 sc.module_sp->GetFileSpec().Dump (s);
626 }
627
628 if (sc.comp_unit != NULL)
629 {
630 s->EOL();
631 s->Indent("compile unit = ");
Jim Ingham517b3b22010-10-27 22:58:34 +0000632 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000633
634 if (sc.function != NULL)
635 {
636 s->EOL();
637 s->Indent("function = ");
Greg Claytonddaf6a72015-07-08 22:32:23 +0000638 s->PutCString (sc.function->GetName().AsCString("<unknown>"));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000639 }
640
641 if (sc.line_entry.line > 0)
642 {
643 s->EOL();
644 s->Indent("location = ");
Greg Clayton6dadd502010-09-02 21:44:10 +0000645 sc.line_entry.DumpStopContext (s, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000646 }
647
648 }
649 else
650 {
651 // If we don't have a comp unit, see if we have a symbol we can print.
652 if (sc.symbol)
653 {
654 s->EOL();
Jim Ingham1460e4b2014-01-10 23:46:59 +0000655 if (IsReExported())
656 s->Indent ("re-exported target = ");
657 else
658 s->Indent("symbol = ");
Greg Claytonddaf6a72015-07-08 22:32:23 +0000659 s->PutCString(sc.symbol->GetName().AsCString("<unknown>"));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000660 }
661 }
662 }
663 }
664
665 if (level == lldb::eDescriptionLevelVerbose)
666 {
667 s->EOL();
668 s->Indent();
669 }
Jim Ingham1391cc72012-09-22 00:04:04 +0000670
671 if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
672 s->Printf (", ");
673 s->Printf ("address = ");
674
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000675 ExecutionContextScope *exe_scope = NULL;
676 Target *target = &m_owner.GetTarget();
677 if (target)
678 exe_scope = target->GetProcessSP().get();
679 if (exe_scope == NULL)
680 exe_scope = target;
681
Jim Ingham8f632662014-03-04 03:09:00 +0000682 if (level == eDescriptionLevelInitial)
Jim Ingham1391cc72012-09-22 00:04:04 +0000683 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
684 else
685 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
Jim Ingham1460e4b2014-01-10 23:46:59 +0000686
687 if (IsIndirect() && m_bp_site_sp)
688 {
689 Address resolved_address;
690 resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
691 Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
692 if (resolved_symbol)
693 {
694 if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
695 s->Printf (", ");
696 else if (level == lldb::eDescriptionLevelVerbose)
697 {
698 s->EOL();
699 s->Indent();
700 }
701 s->Printf ("indirect target = %s", resolved_symbol->GetName().GetCString());
702 }
703 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000704
705 if (level == lldb::eDescriptionLevelVerbose)
706 {
707 s->EOL();
708 s->Indent();
709 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
710
711 s->Indent();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000712 s->Printf ("hit count = %-4u\n", GetHitCount());
713
714 if (m_options_ap.get())
715 {
Jim Ingham01363092010-06-18 01:00:58 +0000716 s->Indent();
717 m_options_ap->GetDescription (s, level);
718 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000719 }
720 s->IndentLess();
721 }
Jim Ingham1391cc72012-09-22 00:04:04 +0000722 else if (level != eDescriptionLevelInitial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000723 {
Jim Ingham01363092010-06-18 01:00:58 +0000724 s->Printf(", %sresolved, hit count = %u ",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000725 (IsResolved() ? "" : "un"),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000726 GetHitCount());
Jim Ingham01363092010-06-18 01:00:58 +0000727 if (m_options_ap.get())
728 {
729 m_options_ap->GetDescription (s, level);
730 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000731 }
732}
733
734void
735BreakpointLocation::Dump(Stream *s) const
736{
737 if (s == NULL)
738 return;
739
Daniel Malead01b2952012-11-29 21:49:15 +0000740 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 +0000741 "hw_index = %i hit_count = %-4u ignore_count = %-4u",
Johnny Chen9ec3c4f2012-01-26 00:08:14 +0000742 GetID(),
743 GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
744 (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()),
Johnny Chen50df1f92012-01-30 22:48:10 +0000745 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled",
Johnny Chen9ec3c4f2012-01-26 00:08:14 +0000746 IsHardware() ? "hardware" : "software",
747 GetHardwareIndex(),
748 GetHitCount(),
749 GetOptionsNoCreate()->GetIgnoreCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000750}
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000751
752void
753BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind)
754{
755 if (!m_being_created
756 && !m_owner.IsInternal()
757 && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
758 {
759 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind,
760 m_owner.shared_from_this());
761 data->GetBreakpointLocationCollection().Add (shared_from_this());
762 m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
763 }
764}
Jim Ingham77fd7382014-09-10 21:40:47 +0000765
766void
767BreakpointLocation::SwapLocation (BreakpointLocationSP swap_from)
768{
769 m_address = swap_from->m_address;
770 m_should_resolve_indirect_functions = swap_from->m_should_resolve_indirect_functions;
771 m_is_reexported = swap_from->m_is_reexported;
772 m_is_indirect = swap_from->m_is_indirect;
773 m_user_expression_sp.reset();
774}