blob: 5ff91102aaddaaf1a6f9ee4c803804329b16806e [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
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012// Other libraries and framework includes
13// Project includes
14#include "lldb/Breakpoint/BreakpointLocation.h"
15#include "lldb/Breakpoint/BreakpointID.h"
16#include "lldb/Breakpoint/StoppointCallbackContext.h"
Jim Ingham5b52f0c2011-06-02 23:58:26 +000017#include "lldb/Core/Debugger.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include "lldb/Core/Log.h"
Greg Clayton1f746072012-08-29 21:13:06 +000019#include "lldb/Core/Module.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000020#include "lldb/Core/StreamString.h"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000021#include "lldb/Core/ValueObject.h"
Bruce Mitchener937e3962015-09-21 16:56:08 +000022#include "lldb/Expression/ExpressionVariable.h"
Jim Ingham151c0322015-09-15 21:13:50 +000023#include "lldb/Expression/UserExpression.h"
Greg Clayton1f746072012-08-29 21:13:06 +000024#include "lldb/Symbol/CompileUnit.h"
25#include "lldb/Symbol/Symbol.h"
Jim Ingham151c0322015-09-15 21:13:50 +000026#include "lldb/Symbol/TypeSystem.h"
Greg Clayton1f746072012-08-29 21:13:06 +000027#include "lldb/Target/Target.h"
28#include "lldb/Target/Process.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Target/Thread.h"
Jim Ingham1b54c882010-06-16 02:00:15 +000030#include "lldb/Target/ThreadSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031
32using namespace lldb;
33using namespace lldb_private;
34
35BreakpointLocation::BreakpointLocation
36(
37 break_id_t loc_id,
38 Breakpoint &owner,
Greg Claytonc0d34462011-02-05 00:38:04 +000039 const Address &addr,
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040 lldb::tid_t tid,
Jim Ingham1460e4b2014-01-10 23:46:59 +000041 bool hardware,
42 bool check_for_resolver
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043) :
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),
Jim Ingham1460e4b2014-01-10 23:46:59 +000046 m_should_resolve_indirect_functions (false),
47 m_is_reexported (false),
48 m_is_indirect (false),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049 m_address (addr),
50 m_owner (owner),
51 m_options_ap (),
Sean Callananb4987e32013-06-06 20:18:50 +000052 m_bp_site_sp (),
53 m_condition_mutex ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054{
Jim Ingham1460e4b2014-01-10 23:46:59 +000055 if (check_for_resolver)
56 {
57 Symbol *symbol = m_address.CalculateSymbolContextSymbol();
58 if (symbol && symbol->IsIndirect())
59 {
60 SetShouldResolveIndirectFunctions (true);
61 }
62 }
63
Jim Ingham1b54c882010-06-16 02:00:15 +000064 SetThreadID (tid);
Jim Inghame6bc6cb2012-02-08 05:23:15 +000065 m_being_created = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066}
67
68BreakpointLocation::~BreakpointLocation()
69{
70 ClearBreakpointSite();
71}
72
73lldb::addr_t
Greg Clayton13238c42010-06-14 04:18:27 +000074BreakpointLocation::GetLoadAddress () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +000075{
Greg Claytonf3ef3d22011-05-22 22:46:53 +000076 return m_address.GetOpcodeLoadAddress (&m_owner.GetTarget());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077}
78
79Address &
80BreakpointLocation::GetAddress ()
81{
82 return m_address;
83}
84
85Breakpoint &
86BreakpointLocation::GetBreakpoint ()
87{
88 return m_owner;
89}
90
Jim Ingham151c0322015-09-15 21:13:50 +000091Target &
92BreakpointLocation::GetTarget()
93{
94 return m_owner.GetTarget();
95}
96
Chris Lattner30fdc8d2010-06-08 16:52:24 +000097bool
Johnny Chenfdad6792012-02-01 19:05:20 +000098BreakpointLocation::IsEnabled () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099{
Johnny Chen50df1f92012-01-30 22:48:10 +0000100 if (!m_owner.IsEnabled())
101 return false;
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000102 else if (m_options_ap.get() != nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000103 return m_options_ap->IsEnabled();
104 else
Johnny Chen50df1f92012-01-30 22:48:10 +0000105 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000106}
107
108void
109BreakpointLocation::SetEnabled (bool enabled)
110{
111 GetLocationOptions()->SetEnabled(enabled);
112 if (enabled)
113 {
114 ResolveBreakpointSite();
115 }
116 else
117 {
118 ClearBreakpointSite();
119 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000120 SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000121}
122
123void
124BreakpointLocation::SetThreadID (lldb::tid_t thread_id)
125{
Jim Ingham1b54c882010-06-16 02:00:15 +0000126 if (thread_id != LLDB_INVALID_THREAD_ID)
127 GetLocationOptions()->SetThreadID(thread_id);
128 else
129 {
130 // If we're resetting this to an invalid thread id, then
131 // don't make an options pointer just to do that.
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000132 if (m_options_ap.get() != nullptr)
Jim Ingham1b54c882010-06-16 02:00:15 +0000133 m_options_ap->SetThreadID (thread_id);
134 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000135 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
136}
137
138lldb::tid_t
139BreakpointLocation::GetThreadID ()
140{
141 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
142 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
143 else
144 return LLDB_INVALID_THREAD_ID;
145}
146
147void
148BreakpointLocation::SetThreadIndex (uint32_t index)
149{
150 if (index != 0)
151 GetLocationOptions()->GetThreadSpec()->SetIndex(index);
152 else
153 {
154 // If we're resetting this to an invalid thread id, then
155 // don't make an options pointer just to do that.
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000156 if (m_options_ap.get() != nullptr)
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000157 m_options_ap->GetThreadSpec()->SetIndex(index);
158 }
159 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000160}
161
162uint32_t
163BreakpointLocation::GetThreadIndex() const
164{
165 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
166 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
167 else
168 return 0;
169}
170
171void
172BreakpointLocation::SetThreadName (const char *thread_name)
173{
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000174 if (thread_name != nullptr)
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000175 GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
176 else
177 {
178 // If we're resetting this to an invalid thread id, then
179 // don't make an options pointer just to do that.
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000180 if (m_options_ap.get() != nullptr)
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000181 m_options_ap->GetThreadSpec()->SetName(thread_name);
182 }
183 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
184}
185
186const char *
187BreakpointLocation::GetThreadName () const
188{
189 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
190 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
191 else
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000192 return nullptr;
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000193}
194
195void
196BreakpointLocation::SetQueueName (const char *queue_name)
197{
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000198 if (queue_name != nullptr)
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000199 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
200 else
201 {
202 // If we're resetting this to an invalid thread id, then
203 // don't make an options pointer just to do that.
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000204 if (m_options_ap.get() != nullptr)
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000205 m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
206 }
207 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
208}
209
210const char *
211BreakpointLocation::GetQueueName () const
212{
213 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
214 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
215 else
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000216 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000217}
218
219bool
220BreakpointLocation::InvokeCallback (StoppointCallbackContext *context)
221{
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000222 if (m_options_ap.get() != nullptr && m_options_ap->HasCallback())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000223 return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID());
Jim Ingham01363092010-06-18 01:00:58 +0000224 else
225 return m_owner.InvokeCallback (context, GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000226}
227
228void
229BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton,
230 bool is_synchronous)
231{
232 // The default "Baton" class will keep a copy of "baton" and won't free
233 // or delete it when it goes goes out of scope.
234 GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000235 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000236}
237
238void
239BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp,
240 bool is_synchronous)
241{
242 GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000243 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000244}
245
246void
247BreakpointLocation::ClearCallback ()
248{
249 GetLocationOptions()->ClearCallback();
250}
251
Jim Ingham36f3b362010-10-14 23:45:03 +0000252void
253BreakpointLocation::SetCondition (const char *condition)
254{
255 GetLocationOptions()->SetCondition (condition);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000256 SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged);
Jim Ingham36f3b362010-10-14 23:45:03 +0000257}
258
Jim Ingham36f3b362010-10-14 23:45:03 +0000259const char *
Sean Callanan3dbf3462013-04-19 07:09:15 +0000260BreakpointLocation::GetConditionText (size_t *hash) const
Jim Ingham36f3b362010-10-14 23:45:03 +0000261{
Sean Callanan3dbf3462013-04-19 07:09:15 +0000262 return GetOptionsNoCreate()->GetConditionText(hash);
263}
264
265bool
266BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
267{
268 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Sean Callananb4987e32013-06-06 20:18:50 +0000269
270 Mutex::Locker evaluation_locker(m_condition_mutex);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000271
272 size_t condition_hash;
273 const char *condition_text = GetConditionText(&condition_hash);
274
275 if (!condition_text)
Sean Callananec537a22013-05-10 21:58:45 +0000276 {
277 m_user_expression_sp.reset();
Sean Callanan3dbf3462013-04-19 07:09:15 +0000278 return false;
Sean Callananec537a22013-05-10 21:58:45 +0000279 }
Sean Callanan3dbf3462013-04-19 07:09:15 +0000280
281 if (condition_hash != m_condition_hash ||
282 !m_user_expression_sp ||
283 !m_user_expression_sp->MatchesContext(exe_ctx))
284 {
Jim Ingham151c0322015-09-15 21:13:50 +0000285 LanguageType language = eLanguageTypeUnknown;
286 // See if we can figure out the language from the frame, otherwise use the default language:
287 CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit();
288 if (comp_unit)
289 language = comp_unit->GetLanguage();
290
291 Error error;
292 m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(condition_text,
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000293 nullptr,
294 language,
295 Expression::eResultTypeAny,
Jim Ingham19a63fc2015-11-03 02:11:24 +0000296 EvaluateExpressionOptions(),
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000297 error));
Jim Ingham151c0322015-09-15 21:13:50 +0000298 if (error.Fail())
299 {
300 if (log)
301 log->Printf("Error getting condition expression: %s.", error.AsCString());
302 m_user_expression_sp.reset();
303 return true;
304 }
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000305
Sean Callanan3dbf3462013-04-19 07:09:15 +0000306 StreamString errors;
307
308 if (!m_user_expression_sp->Parse(errors,
309 exe_ctx,
310 eExecutionPolicyOnlyWhenNeeded,
Greg Clayton23f8c952014-03-24 23:10:19 +0000311 true,
312 false))
Sean Callanan3dbf3462013-04-19 07:09:15 +0000313 {
314 error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s",
315 errors.GetData());
316 m_user_expression_sp.reset();
317 return false;
318 }
319
320 m_condition_hash = condition_hash;
321 }
322
323 // We need to make sure the user sees any parse errors in their condition, so we'll hook the
324 // constructor errors up to the debugger's Async I/O.
325
326 ValueObjectSP result_value_sp;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000327
328 EvaluateExpressionOptions options;
329 options.SetUnwindOnError(true);
330 options.SetIgnoreBreakpoints(true);
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000331 options.SetTryAllThreads(true);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000332
333 Error expr_error;
334
335 StreamString execution_errors;
336
Sean Callananbc8ac342015-09-04 20:49:51 +0000337 ExpressionVariableSP result_variable_sp;
Sean Callanan3dbf3462013-04-19 07:09:15 +0000338
Jim Ingham1624a2d2014-05-05 02:26:40 +0000339 ExpressionResults result_code =
Sean Callanan3dbf3462013-04-19 07:09:15 +0000340 m_user_expression_sp->Execute(execution_errors,
341 exe_ctx,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000342 options,
Sean Callanan3dbf3462013-04-19 07:09:15 +0000343 m_user_expression_sp,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000344 result_variable_sp);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000345
346 bool ret;
347
Jim Ingham8646d3c2014-05-05 02:47:44 +0000348 if (result_code == eExpressionCompleted)
Sean Callanan3dbf3462013-04-19 07:09:15 +0000349 {
Sean Callanan467441d52013-05-29 20:22:18 +0000350 if (!result_variable_sp)
351 {
Sean Callanan467441d52013-05-29 20:22:18 +0000352 error.SetErrorString("Expression did not return a result");
Sean Callanan879425f2013-06-24 17:58:46 +0000353 return false;
Sean Callanan467441d52013-05-29 20:22:18 +0000354 }
355
Sean Callanan3dbf3462013-04-19 07:09:15 +0000356 result_value_sp = result_variable_sp->GetValueObject();
357
358 if (result_value_sp)
359 {
Jim Ingham98e6daf2015-10-31 00:02:18 +0000360 ret = result_value_sp->IsLogicalTrue(error);
361 if (log)
Sean Callanan3dbf3462013-04-19 07:09:15 +0000362 {
Jim Ingham98e6daf2015-10-31 00:02:18 +0000363 if (error.Success())
364 {
Sean Callanan3dbf3462013-04-19 07:09:15 +0000365 log->Printf("Condition successfully evaluated, result is %s.\n",
366 ret ? "true" : "false");
Jim Ingham98e6daf2015-10-31 00:02:18 +0000367 }
368 else
369 {
370 error.SetErrorString("Failed to get an integer result from the expression");
371 ret = false;
372 }
373
Sean Callanan3dbf3462013-04-19 07:09:15 +0000374 }
375 }
376 else
377 {
378 ret = false;
379 error.SetErrorString("Failed to get any result from the expression");
380 }
381 }
382 else
383 {
384 ret = false;
385 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData());
386 }
387
388 return ret;
Jim Ingham36f3b362010-10-14 23:45:03 +0000389}
390
Greg Claytonc982c762010-07-09 20:39:50 +0000391uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000392BreakpointLocation::GetIgnoreCount ()
393{
Jim Ingham05407f62010-06-22 21:12:54 +0000394 return GetOptionsNoCreate()->GetIgnoreCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000395}
396
397void
Greg Claytonc982c762010-07-09 20:39:50 +0000398BreakpointLocation::SetIgnoreCount (uint32_t n)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000399{
400 GetLocationOptions()->SetIgnoreCount(n);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000401 SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000402}
403
Jim Ingham0fd1b752012-06-26 22:27:55 +0000404void
405BreakpointLocation::DecrementIgnoreCount()
406{
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000407 if (m_options_ap.get() != nullptr)
Jim Ingham0fd1b752012-06-26 22:27:55 +0000408 {
409 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
410 if (loc_ignore != 0)
411 m_options_ap->SetIgnoreCount(loc_ignore - 1);
412 }
413}
414
415bool
416BreakpointLocation::IgnoreCountShouldStop()
417{
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000418 if (m_options_ap.get() != nullptr)
Jim Ingham0fd1b752012-06-26 22:27:55 +0000419 {
420 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
421 if (loc_ignore != 0)
422 {
423 m_owner.DecrementIgnoreCount();
424 DecrementIgnoreCount(); // Have to decrement our owners' ignore count, since it won't get a
425 // chance to.
426 return false;
427 }
428 }
429 return true;
430}
431
Jim Ingham1b54c882010-06-16 02:00:15 +0000432const BreakpointOptions *
Jim Ingham05407f62010-06-22 21:12:54 +0000433BreakpointLocation::GetOptionsNoCreate () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000434{
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000435 if (m_options_ap.get() != nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000436 return m_options_ap.get();
437 else
438 return m_owner.GetOptions ();
439}
440
441BreakpointOptions *
442BreakpointLocation::GetLocationOptions ()
443{
Jim Ingham01363092010-06-18 01:00:58 +0000444 // If we make the copy we don't copy the callbacks because that is potentially
445 // expensive and we don't want to do that for the simple case where someone is
446 // just disabling the location.
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000447 if (m_options_ap.get() == nullptr)
Jim Ingham01363092010-06-18 01:00:58 +0000448 m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ()));
449
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000450 return m_options_ap.get();
451}
452
Jim Ingham1b54c882010-06-16 02:00:15 +0000453bool
454BreakpointLocation::ValidForThisThread (Thread *thread)
455{
Jim Ingham05407f62010-06-22 21:12:54 +0000456 return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
Jim Ingham1b54c882010-06-16 02:00:15 +0000457}
458
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000459// RETURNS - true if we should stop at this breakpoint, false if we
Jim Ingham1b54c882010-06-16 02:00:15 +0000460// should continue. Note, we don't check the thread spec for the breakpoint
461// here, since if the breakpoint is not for this thread, then the event won't
462// even get reported, so the check is redundant.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000463
464bool
465BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
466{
467 bool should_stop = true;
Greg Clayton5160ce52013-03-27 23:08:40 +0000468 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000469
Jim Inghama672ece2014-10-22 01:54:17 +0000470 // Do this first, if a location is disabled, it shouldn't increment its hit count.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000471 if (!IsEnabled())
472 return false;
473
Jim Ingham0fd1b752012-06-26 22:27:55 +0000474 if (!IgnoreCountShouldStop())
475 return false;
476
477 if (!m_owner.IgnoreCountShouldStop())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000478 return false;
479
Jim Ingham36f3b362010-10-14 23:45:03 +0000480 // We only run synchronous callbacks in ShouldStop:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000481 context->is_synchronous = true;
482 should_stop = InvokeCallback (context);
Jim Ingham36f3b362010-10-14 23:45:03 +0000483
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000484 if (log)
Jim Ingham36f3b362010-10-14 23:45:03 +0000485 {
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000486 StreamString s;
487 GetDescription (&s, lldb::eDescriptionLevelVerbose);
488 log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000489 }
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000490
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000491 return should_stop;
492}
493
Jim Inghama672ece2014-10-22 01:54:17 +0000494void
495BreakpointLocation::BumpHitCount()
496{
497 if (IsEnabled())
Jim Inghamd762df82015-01-15 01:41:04 +0000498 {
499 // Step our hit count, and also step the hit count of the owner.
Jim Inghama672ece2014-10-22 01:54:17 +0000500 IncrementHitCount();
Jim Inghamd762df82015-01-15 01:41:04 +0000501 m_owner.IncrementHitCount();
502 }
503}
504
505void
506BreakpointLocation::UndoBumpHitCount()
507{
508 if (IsEnabled())
509 {
510 // Step our hit count, and also step the hit count of the owner.
511 DecrementHitCount();
512 m_owner.DecrementHitCount();
513 }
Jim Inghama672ece2014-10-22 01:54:17 +0000514}
515
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000516bool
517BreakpointLocation::IsResolved () const
518{
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000519 return m_bp_site_sp.get() != nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000520}
521
Jim Ingham36f3b362010-10-14 23:45:03 +0000522lldb::BreakpointSiteSP
523BreakpointLocation::GetBreakpointSite() const
524{
525 return m_bp_site_sp;
526}
527
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000528bool
529BreakpointLocation::ResolveBreakpointSite ()
530{
531 if (m_bp_site_sp)
532 return true;
533
Greg Claytonf5e56de2010-09-14 23:36:40 +0000534 Process *process = m_owner.GetTarget().GetProcessSP().get();
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000535 if (process == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000536 return false;
537
Greg Claytoneb023e72013-10-11 19:48:25 +0000538 lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), m_owner.IsHardware());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000539
Stephen Wilson50bd94f2010-07-17 00:56:13 +0000540 if (new_id == LLDB_INVALID_BREAK_ID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000541 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000542 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000543 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000544 log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n",
Greg Claytonf3ef3d22011-05-22 22:46:53 +0000545 m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000546 return false;
547 }
548
549 return true;
550}
551
552bool
553BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp)
554{
555 m_bp_site_sp = bp_site_sp;
Ilia K9b618d22015-04-09 12:55:13 +0000556 SendBreakpointLocationChangedEvent (eBreakpointEventTypeLocationsResolved);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000557 return true;
558}
559
560bool
561BreakpointLocation::ClearBreakpointSite ()
562{
563 if (m_bp_site_sp.get())
564 {
Jim Ingham15783132014-03-12 22:03:13 +0000565 ProcessSP process_sp(m_owner.GetTarget().GetProcessSP());
566 // If the process exists, get it to remove the owner, it will remove the physical implementation
567 // of the breakpoint as well if there are no more owners. Otherwise just remove this owner.
568 if (process_sp)
569 process_sp->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(),
Jim Ingham01363092010-06-18 01:00:58 +0000570 GetID(), m_bp_site_sp);
Jim Ingham15783132014-03-12 22:03:13 +0000571 else
572 m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID());
573
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000574 m_bp_site_sp.reset();
575 return true;
576 }
577 return false;
578}
579
580void
581BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
582{
583 SymbolContext sc;
Jim Ingham1391cc72012-09-22 00:04:04 +0000584
585 // If the description level is "initial" then the breakpoint is printing out our initial state,
586 // and we should let it decide how it wants to print our label.
587 if (level != eDescriptionLevelInitial)
588 {
589 s->Indent();
590 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
591 }
592
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000593 if (level == lldb::eDescriptionLevelBrief)
594 return;
595
Jim Ingham1391cc72012-09-22 00:04:04 +0000596 if (level != eDescriptionLevelInitial)
597 s->PutCString(": ");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000598
599 if (level == lldb::eDescriptionLevelVerbose)
600 s->IndentMore();
601
602 if (m_address.IsSectionOffset())
603 {
604 m_address.CalculateSymbolContext(&sc);
605
Jim Ingham1391cc72012-09-22 00:04:04 +0000606 if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000607 {
Jim Ingham1460e4b2014-01-10 23:46:59 +0000608 if (IsReExported())
609 s->PutCString ("re-exported target = ");
610 else
611 s->PutCString("where = ");
Jason Molendac980fa92015-02-13 23:24:21 +0000612 sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false, true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000613 }
614 else
615 {
616 if (sc.module_sp)
617 {
618 s->EOL();
619 s->Indent("module = ");
620 sc.module_sp->GetFileSpec().Dump (s);
621 }
622
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000623 if (sc.comp_unit != nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000624 {
625 s->EOL();
626 s->Indent("compile unit = ");
Jim Ingham517b3b22010-10-27 22:58:34 +0000627 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000628
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000629 if (sc.function != nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000630 {
631 s->EOL();
632 s->Indent("function = ");
Greg Claytonddaf6a72015-07-08 22:32:23 +0000633 s->PutCString (sc.function->GetName().AsCString("<unknown>"));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000634 }
635
636 if (sc.line_entry.line > 0)
637 {
638 s->EOL();
639 s->Indent("location = ");
Greg Clayton6dadd502010-09-02 21:44:10 +0000640 sc.line_entry.DumpStopContext (s, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000641 }
642
643 }
644 else
645 {
646 // If we don't have a comp unit, see if we have a symbol we can print.
647 if (sc.symbol)
648 {
649 s->EOL();
Jim Ingham1460e4b2014-01-10 23:46:59 +0000650 if (IsReExported())
651 s->Indent ("re-exported target = ");
652 else
653 s->Indent("symbol = ");
Greg Claytonddaf6a72015-07-08 22:32:23 +0000654 s->PutCString(sc.symbol->GetName().AsCString("<unknown>"));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000655 }
656 }
657 }
658 }
659
660 if (level == lldb::eDescriptionLevelVerbose)
661 {
662 s->EOL();
663 s->Indent();
664 }
Jim Ingham1391cc72012-09-22 00:04:04 +0000665
666 if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
667 s->Printf (", ");
668 s->Printf ("address = ");
669
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000670 ExecutionContextScope *exe_scope = nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000671 Target *target = &m_owner.GetTarget();
672 if (target)
673 exe_scope = target->GetProcessSP().get();
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000674 if (exe_scope == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000675 exe_scope = target;
676
Jim Ingham8f632662014-03-04 03:09:00 +0000677 if (level == eDescriptionLevelInitial)
Jim Ingham1391cc72012-09-22 00:04:04 +0000678 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
679 else
680 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
Jim Ingham1460e4b2014-01-10 23:46:59 +0000681
682 if (IsIndirect() && m_bp_site_sp)
683 {
684 Address resolved_address;
685 resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
686 Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
687 if (resolved_symbol)
688 {
689 if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
690 s->Printf (", ");
691 else if (level == lldb::eDescriptionLevelVerbose)
692 {
693 s->EOL();
694 s->Indent();
695 }
696 s->Printf ("indirect target = %s", resolved_symbol->GetName().GetCString());
697 }
698 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000699
700 if (level == lldb::eDescriptionLevelVerbose)
701 {
702 s->EOL();
703 s->Indent();
704 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
705
706 s->Indent();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000707 s->Printf ("hit count = %-4u\n", GetHitCount());
708
709 if (m_options_ap.get())
710 {
Jim Ingham01363092010-06-18 01:00:58 +0000711 s->Indent();
712 m_options_ap->GetDescription (s, level);
713 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000714 }
715 s->IndentLess();
716 }
Jim Ingham1391cc72012-09-22 00:04:04 +0000717 else if (level != eDescriptionLevelInitial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718 {
Jim Ingham01363092010-06-18 01:00:58 +0000719 s->Printf(", %sresolved, hit count = %u ",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000720 (IsResolved() ? "" : "un"),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000721 GetHitCount());
Jim Ingham01363092010-06-18 01:00:58 +0000722 if (m_options_ap.get())
723 {
724 m_options_ap->GetDescription (s, level);
725 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000726 }
727}
728
729void
730BreakpointLocation::Dump(Stream *s) const
731{
Eugene Zelenko16fd7512015-10-30 18:50:12 +0000732 if (s == nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000733 return;
734
Daniel Malead01b2952012-11-29 21:49:15 +0000735 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 +0000736 "hw_index = %i hit_count = %-4u ignore_count = %-4u",
Johnny Chen9ec3c4f2012-01-26 00:08:14 +0000737 GetID(),
738 GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
739 (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()),
Johnny Chen50df1f92012-01-30 22:48:10 +0000740 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled",
Johnny Chen9ec3c4f2012-01-26 00:08:14 +0000741 IsHardware() ? "hardware" : "software",
742 GetHardwareIndex(),
743 GetHitCount(),
744 GetOptionsNoCreate()->GetIgnoreCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000745}
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000746
747void
748BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind)
749{
750 if (!m_being_created
751 && !m_owner.IsInternal()
752 && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
753 {
754 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind,
755 m_owner.shared_from_this());
756 data->GetBreakpointLocationCollection().Add (shared_from_this());
757 m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
758 }
759}
Jim Ingham77fd7382014-09-10 21:40:47 +0000760
761void
762BreakpointLocation::SwapLocation (BreakpointLocationSP swap_from)
763{
764 m_address = swap_from->m_address;
765 m_should_resolve_indirect_functions = swap_from->m_should_resolve_indirect_functions;
766 m_is_reexported = swap_from->m_is_reexported;
767 m_is_indirect = swap_from->m_is_indirect;
768 m_user_expression_sp.reset();
769}