blob: 0dab0e16bf16b4ab1f3c3643caba6b5e987f7961 [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"
Jim Ingham151c0322015-09-15 21:13:50 +000024#include "lldb/Expression/UserExpression.h"
Greg Clayton1f746072012-08-29 21:13:06 +000025#include "lldb/Symbol/CompileUnit.h"
26#include "lldb/Symbol/Symbol.h"
Jim Ingham151c0322015-09-15 21:13:50 +000027#include "lldb/Symbol/TypeSystem.h"
Greg Clayton1f746072012-08-29 21:13:06 +000028#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
Jim Ingham151c0322015-09-15 21:13:50 +000092Target &
93BreakpointLocation::GetTarget()
94{
95 return m_owner.GetTarget();
96}
97
Chris Lattner30fdc8d2010-06-08 16:52:24 +000098bool
Johnny Chenfdad6792012-02-01 19:05:20 +000099BreakpointLocation::IsEnabled () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000100{
Johnny Chen50df1f92012-01-30 22:48:10 +0000101 if (!m_owner.IsEnabled())
102 return false;
103 else if (m_options_ap.get() != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000104 return m_options_ap->IsEnabled();
105 else
Johnny Chen50df1f92012-01-30 22:48:10 +0000106 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000107}
108
109void
110BreakpointLocation::SetEnabled (bool enabled)
111{
112 GetLocationOptions()->SetEnabled(enabled);
113 if (enabled)
114 {
115 ResolveBreakpointSite();
116 }
117 else
118 {
119 ClearBreakpointSite();
120 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000121 SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000122}
123
124void
125BreakpointLocation::SetThreadID (lldb::tid_t thread_id)
126{
Jim Ingham1b54c882010-06-16 02:00:15 +0000127 if (thread_id != LLDB_INVALID_THREAD_ID)
128 GetLocationOptions()->SetThreadID(thread_id);
129 else
130 {
131 // If we're resetting this to an invalid thread id, then
132 // don't make an options pointer just to do that.
133 if (m_options_ap.get() != NULL)
134 m_options_ap->SetThreadID (thread_id);
135 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000136 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
137}
138
139lldb::tid_t
140BreakpointLocation::GetThreadID ()
141{
142 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
143 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
144 else
145 return LLDB_INVALID_THREAD_ID;
146}
147
148void
149BreakpointLocation::SetThreadIndex (uint32_t index)
150{
151 if (index != 0)
152 GetLocationOptions()->GetThreadSpec()->SetIndex(index);
153 else
154 {
155 // If we're resetting this to an invalid thread id, then
156 // don't make an options pointer just to do that.
157 if (m_options_ap.get() != NULL)
158 m_options_ap->GetThreadSpec()->SetIndex(index);
159 }
160 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
161
162}
163
164uint32_t
165BreakpointLocation::GetThreadIndex() const
166{
167 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
168 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
169 else
170 return 0;
171}
172
173void
174BreakpointLocation::SetThreadName (const char *thread_name)
175{
176 if (thread_name != NULL)
177 GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
178 else
179 {
180 // If we're resetting this to an invalid thread id, then
181 // don't make an options pointer just to do that.
182 if (m_options_ap.get() != NULL)
183 m_options_ap->GetThreadSpec()->SetName(thread_name);
184 }
185 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
186}
187
188const char *
189BreakpointLocation::GetThreadName () const
190{
191 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
192 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
193 else
194 return NULL;
195}
196
197void
198BreakpointLocation::SetQueueName (const char *queue_name)
199{
200 if (queue_name != NULL)
201 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
202 else
203 {
204 // If we're resetting this to an invalid thread id, then
205 // don't make an options pointer just to do that.
206 if (m_options_ap.get() != NULL)
207 m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
208 }
209 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
210}
211
212const char *
213BreakpointLocation::GetQueueName () const
214{
215 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
216 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
217 else
218 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000219}
220
221bool
222BreakpointLocation::InvokeCallback (StoppointCallbackContext *context)
223{
Jim Ingham01363092010-06-18 01:00:58 +0000224 if (m_options_ap.get() != NULL && m_options_ap->HasCallback())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000225 return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID());
Jim Ingham01363092010-06-18 01:00:58 +0000226 else
227 return m_owner.InvokeCallback (context, GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000228}
229
230void
231BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton,
232 bool is_synchronous)
233{
234 // The default "Baton" class will keep a copy of "baton" and won't free
235 // or delete it when it goes goes out of scope.
236 GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000237 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000238}
239
240void
241BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp,
242 bool is_synchronous)
243{
244 GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000245 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000246}
247
Jim Ingham36f3b362010-10-14 23:45:03 +0000248
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000249void
250BreakpointLocation::ClearCallback ()
251{
252 GetLocationOptions()->ClearCallback();
253}
254
Jim Ingham36f3b362010-10-14 23:45:03 +0000255void
256BreakpointLocation::SetCondition (const char *condition)
257{
258 GetLocationOptions()->SetCondition (condition);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000259 SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged);
Jim Ingham36f3b362010-10-14 23:45:03 +0000260}
261
Jim Ingham36f3b362010-10-14 23:45:03 +0000262const char *
Sean Callanan3dbf3462013-04-19 07:09:15 +0000263BreakpointLocation::GetConditionText (size_t *hash) const
Jim Ingham36f3b362010-10-14 23:45:03 +0000264{
Sean Callanan3dbf3462013-04-19 07:09:15 +0000265 return GetOptionsNoCreate()->GetConditionText(hash);
266}
267
268bool
269BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
270{
271 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Sean Callananb4987e32013-06-06 20:18:50 +0000272
273 Mutex::Locker evaluation_locker(m_condition_mutex);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000274
275 size_t condition_hash;
276 const char *condition_text = GetConditionText(&condition_hash);
277
278 if (!condition_text)
Sean Callananec537a22013-05-10 21:58:45 +0000279 {
280 m_user_expression_sp.reset();
Sean Callanan3dbf3462013-04-19 07:09:15 +0000281 return false;
Sean Callananec537a22013-05-10 21:58:45 +0000282 }
Sean Callanan3dbf3462013-04-19 07:09:15 +0000283
284 if (condition_hash != m_condition_hash ||
285 !m_user_expression_sp ||
286 !m_user_expression_sp->MatchesContext(exe_ctx))
287 {
Jim Ingham151c0322015-09-15 21:13:50 +0000288 LanguageType language = eLanguageTypeUnknown;
289 // See if we can figure out the language from the frame, otherwise use the default language:
290 CompileUnit *comp_unit = m_address.CalculateSymbolContextCompileUnit();
291 if (comp_unit)
292 language = comp_unit->GetLanguage();
293
294 Error error;
295 m_user_expression_sp.reset(GetTarget().GetUserExpressionForLanguage(condition_text,
296 NULL,
297 language,
298 Expression::eResultTypeAny,
299 error));
300 if (error.Fail())
301 {
302 if (log)
303 log->Printf("Error getting condition expression: %s.", error.AsCString());
304 m_user_expression_sp.reset();
305 return true;
306 }
307
Sean Callanan3dbf3462013-04-19 07:09:15 +0000308
309 StreamString errors;
310
311 if (!m_user_expression_sp->Parse(errors,
312 exe_ctx,
313 eExecutionPolicyOnlyWhenNeeded,
Greg Clayton23f8c952014-03-24 23:10:19 +0000314 true,
315 false))
Sean Callanan3dbf3462013-04-19 07:09:15 +0000316 {
317 error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s",
318 errors.GetData());
319 m_user_expression_sp.reset();
320 return false;
321 }
322
323 m_condition_hash = condition_hash;
324 }
325
326 // We need to make sure the user sees any parse errors in their condition, so we'll hook the
327 // constructor errors up to the debugger's Async I/O.
328
329 ValueObjectSP result_value_sp;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000330
331 EvaluateExpressionOptions options;
332 options.SetUnwindOnError(true);
333 options.SetIgnoreBreakpoints(true);
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000334 options.SetTryAllThreads(true);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000335
336 Error expr_error;
337
338 StreamString execution_errors;
339
Sean Callananbc8ac342015-09-04 20:49:51 +0000340 ExpressionVariableSP result_variable_sp;
Sean Callanan3dbf3462013-04-19 07:09:15 +0000341
Jim Ingham1624a2d2014-05-05 02:26:40 +0000342 ExpressionResults result_code =
Sean Callanan3dbf3462013-04-19 07:09:15 +0000343 m_user_expression_sp->Execute(execution_errors,
344 exe_ctx,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000345 options,
Sean Callanan3dbf3462013-04-19 07:09:15 +0000346 m_user_expression_sp,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000347 result_variable_sp);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000348
349 bool ret;
350
Jim Ingham8646d3c2014-05-05 02:47:44 +0000351 if (result_code == eExpressionCompleted)
Sean Callanan3dbf3462013-04-19 07:09:15 +0000352 {
Sean Callanan467441d52013-05-29 20:22:18 +0000353 if (!result_variable_sp)
354 {
Sean Callanan467441d52013-05-29 20:22:18 +0000355 error.SetErrorString("Expression did not return a result");
Sean Callanan879425f2013-06-24 17:58:46 +0000356 return false;
Sean Callanan467441d52013-05-29 20:22:18 +0000357 }
358
Sean Callanan3dbf3462013-04-19 07:09:15 +0000359 result_value_sp = result_variable_sp->GetValueObject();
360
361 if (result_value_sp)
362 {
363 Scalar scalar_value;
364 if (result_value_sp->ResolveValue (scalar_value))
365 {
366 if (scalar_value.ULongLong(1) == 0)
367 ret = false;
368 else
369 ret = true;
370 if (log)
371 log->Printf("Condition successfully evaluated, result is %s.\n",
372 ret ? "true" : "false");
373 }
374 else
375 {
376 ret = false;
377 error.SetErrorString("Failed to get an integer result from the expression");
378 }
379 }
380 else
381 {
382 ret = false;
383 error.SetErrorString("Failed to get any result from the expression");
384 }
385 }
386 else
387 {
388 ret = false;
389 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData());
390 }
391
392 return ret;
Jim Ingham36f3b362010-10-14 23:45:03 +0000393}
394
Greg Claytonc982c762010-07-09 20:39:50 +0000395uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000396BreakpointLocation::GetIgnoreCount ()
397{
Jim Ingham05407f62010-06-22 21:12:54 +0000398 return GetOptionsNoCreate()->GetIgnoreCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000399}
400
401void
Greg Claytonc982c762010-07-09 20:39:50 +0000402BreakpointLocation::SetIgnoreCount (uint32_t n)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000403{
404 GetLocationOptions()->SetIgnoreCount(n);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000405 SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000406}
407
Jim Ingham0fd1b752012-06-26 22:27:55 +0000408void
409BreakpointLocation::DecrementIgnoreCount()
410{
411 if (m_options_ap.get() != NULL)
412 {
413 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
414 if (loc_ignore != 0)
415 m_options_ap->SetIgnoreCount(loc_ignore - 1);
416 }
417}
418
419bool
420BreakpointLocation::IgnoreCountShouldStop()
421{
422 if (m_options_ap.get() != NULL)
423 {
424 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
425 if (loc_ignore != 0)
426 {
427 m_owner.DecrementIgnoreCount();
428 DecrementIgnoreCount(); // Have to decrement our owners' ignore count, since it won't get a
429 // chance to.
430 return false;
431 }
432 }
433 return true;
434}
435
Jim Ingham1b54c882010-06-16 02:00:15 +0000436const BreakpointOptions *
Jim Ingham05407f62010-06-22 21:12:54 +0000437BreakpointLocation::GetOptionsNoCreate () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000438{
439 if (m_options_ap.get() != NULL)
440 return m_options_ap.get();
441 else
442 return m_owner.GetOptions ();
443}
444
445BreakpointOptions *
446BreakpointLocation::GetLocationOptions ()
447{
Jim Ingham01363092010-06-18 01:00:58 +0000448 // If we make the copy we don't copy the callbacks because that is potentially
449 // expensive and we don't want to do that for the simple case where someone is
450 // just disabling the location.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000451 if (m_options_ap.get() == NULL)
Jim Ingham01363092010-06-18 01:00:58 +0000452 m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ()));
453
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000454 return m_options_ap.get();
455}
456
Jim Ingham1b54c882010-06-16 02:00:15 +0000457bool
458BreakpointLocation::ValidForThisThread (Thread *thread)
459{
Jim Ingham05407f62010-06-22 21:12:54 +0000460 return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
Jim Ingham1b54c882010-06-16 02:00:15 +0000461}
462
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000463// RETURNS - true if we should stop at this breakpoint, false if we
Jim Ingham1b54c882010-06-16 02:00:15 +0000464// should continue. Note, we don't check the thread spec for the breakpoint
465// here, since if the breakpoint is not for this thread, then the event won't
466// even get reported, so the check is redundant.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000467
468bool
469BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
470{
471 bool should_stop = true;
Greg Clayton5160ce52013-03-27 23:08:40 +0000472 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000473
Jim Inghama672ece2014-10-22 01:54:17 +0000474 // Do this first, if a location is disabled, it shouldn't increment its hit count.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000475 if (!IsEnabled())
476 return false;
477
Jim Ingham0fd1b752012-06-26 22:27:55 +0000478 if (!IgnoreCountShouldStop())
479 return false;
480
481 if (!m_owner.IgnoreCountShouldStop())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000482 return false;
483
Jim Ingham36f3b362010-10-14 23:45:03 +0000484 // We only run synchronous callbacks in ShouldStop:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000485 context->is_synchronous = true;
486 should_stop = InvokeCallback (context);
Jim Ingham36f3b362010-10-14 23:45:03 +0000487
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000488 if (log)
Jim Ingham36f3b362010-10-14 23:45:03 +0000489 {
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000490 StreamString s;
491 GetDescription (&s, lldb::eDescriptionLevelVerbose);
492 log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000493 }
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000494
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000495 return should_stop;
496}
497
Jim Inghama672ece2014-10-22 01:54:17 +0000498void
499BreakpointLocation::BumpHitCount()
500{
501 if (IsEnabled())
Jim Inghamd762df82015-01-15 01:41:04 +0000502 {
503 // Step our hit count, and also step the hit count of the owner.
Jim Inghama672ece2014-10-22 01:54:17 +0000504 IncrementHitCount();
Jim Inghamd762df82015-01-15 01:41:04 +0000505 m_owner.IncrementHitCount();
506 }
507}
508
509void
510BreakpointLocation::UndoBumpHitCount()
511{
512 if (IsEnabled())
513 {
514 // Step our hit count, and also step the hit count of the owner.
515 DecrementHitCount();
516 m_owner.DecrementHitCount();
517 }
Jim Inghama672ece2014-10-22 01:54:17 +0000518}
519
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000520bool
521BreakpointLocation::IsResolved () const
522{
523 return m_bp_site_sp.get() != NULL;
524}
525
Jim Ingham36f3b362010-10-14 23:45:03 +0000526lldb::BreakpointSiteSP
527BreakpointLocation::GetBreakpointSite() const
528{
529 return m_bp_site_sp;
530}
531
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000532bool
533BreakpointLocation::ResolveBreakpointSite ()
534{
535 if (m_bp_site_sp)
536 return true;
537
Greg Claytonf5e56de2010-09-14 23:36:40 +0000538 Process *process = m_owner.GetTarget().GetProcessSP().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000539 if (process == NULL)
540 return false;
541
Greg Claytoneb023e72013-10-11 19:48:25 +0000542 lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), m_owner.IsHardware());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000543
Stephen Wilson50bd94f2010-07-17 00:56:13 +0000544 if (new_id == LLDB_INVALID_BREAK_ID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000545 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000546 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000547 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000548 log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n",
Greg Claytonf3ef3d22011-05-22 22:46:53 +0000549 m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000550 return false;
551 }
552
553 return true;
554}
555
556bool
557BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp)
558{
559 m_bp_site_sp = bp_site_sp;
Ilia K9b618d22015-04-09 12:55:13 +0000560 SendBreakpointLocationChangedEvent (eBreakpointEventTypeLocationsResolved);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000561 return true;
562}
563
564bool
565BreakpointLocation::ClearBreakpointSite ()
566{
567 if (m_bp_site_sp.get())
568 {
Jim Ingham15783132014-03-12 22:03:13 +0000569 ProcessSP process_sp(m_owner.GetTarget().GetProcessSP());
570 // If the process exists, get it to remove the owner, it will remove the physical implementation
571 // of the breakpoint as well if there are no more owners. Otherwise just remove this owner.
572 if (process_sp)
573 process_sp->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(),
Jim Ingham01363092010-06-18 01:00:58 +0000574 GetID(), m_bp_site_sp);
Jim Ingham15783132014-03-12 22:03:13 +0000575 else
576 m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID());
577
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000578 m_bp_site_sp.reset();
579 return true;
580 }
581 return false;
582}
583
584void
585BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
586{
587 SymbolContext sc;
Jim Ingham1391cc72012-09-22 00:04:04 +0000588
589 // If the description level is "initial" then the breakpoint is printing out our initial state,
590 // and we should let it decide how it wants to print our label.
591 if (level != eDescriptionLevelInitial)
592 {
593 s->Indent();
594 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
595 }
596
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000597 if (level == lldb::eDescriptionLevelBrief)
598 return;
599
Jim Ingham1391cc72012-09-22 00:04:04 +0000600 if (level != eDescriptionLevelInitial)
601 s->PutCString(": ");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000602
603 if (level == lldb::eDescriptionLevelVerbose)
604 s->IndentMore();
605
606 if (m_address.IsSectionOffset())
607 {
608 m_address.CalculateSymbolContext(&sc);
609
Jim Ingham1391cc72012-09-22 00:04:04 +0000610 if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000611 {
Jim Ingham1460e4b2014-01-10 23:46:59 +0000612 if (IsReExported())
613 s->PutCString ("re-exported target = ");
614 else
615 s->PutCString("where = ");
Jason Molendac980fa92015-02-13 23:24:21 +0000616 sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false, true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000617 }
618 else
619 {
620 if (sc.module_sp)
621 {
622 s->EOL();
623 s->Indent("module = ");
624 sc.module_sp->GetFileSpec().Dump (s);
625 }
626
627 if (sc.comp_unit != NULL)
628 {
629 s->EOL();
630 s->Indent("compile unit = ");
Jim Ingham517b3b22010-10-27 22:58:34 +0000631 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000632
633 if (sc.function != NULL)
634 {
635 s->EOL();
636 s->Indent("function = ");
Greg Claytonddaf6a72015-07-08 22:32:23 +0000637 s->PutCString (sc.function->GetName().AsCString("<unknown>"));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000638 }
639
640 if (sc.line_entry.line > 0)
641 {
642 s->EOL();
643 s->Indent("location = ");
Greg Clayton6dadd502010-09-02 21:44:10 +0000644 sc.line_entry.DumpStopContext (s, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000645 }
646
647 }
648 else
649 {
650 // If we don't have a comp unit, see if we have a symbol we can print.
651 if (sc.symbol)
652 {
653 s->EOL();
Jim Ingham1460e4b2014-01-10 23:46:59 +0000654 if (IsReExported())
655 s->Indent ("re-exported target = ");
656 else
657 s->Indent("symbol = ");
Greg Claytonddaf6a72015-07-08 22:32:23 +0000658 s->PutCString(sc.symbol->GetName().AsCString("<unknown>"));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000659 }
660 }
661 }
662 }
663
664 if (level == lldb::eDescriptionLevelVerbose)
665 {
666 s->EOL();
667 s->Indent();
668 }
Jim Ingham1391cc72012-09-22 00:04:04 +0000669
670 if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
671 s->Printf (", ");
672 s->Printf ("address = ");
673
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000674 ExecutionContextScope *exe_scope = NULL;
675 Target *target = &m_owner.GetTarget();
676 if (target)
677 exe_scope = target->GetProcessSP().get();
678 if (exe_scope == NULL)
679 exe_scope = target;
680
Jim Ingham8f632662014-03-04 03:09:00 +0000681 if (level == eDescriptionLevelInitial)
Jim Ingham1391cc72012-09-22 00:04:04 +0000682 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
683 else
684 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
Jim Ingham1460e4b2014-01-10 23:46:59 +0000685
686 if (IsIndirect() && m_bp_site_sp)
687 {
688 Address resolved_address;
689 resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
690 Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
691 if (resolved_symbol)
692 {
693 if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
694 s->Printf (", ");
695 else if (level == lldb::eDescriptionLevelVerbose)
696 {
697 s->EOL();
698 s->Indent();
699 }
700 s->Printf ("indirect target = %s", resolved_symbol->GetName().GetCString());
701 }
702 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000703
704 if (level == lldb::eDescriptionLevelVerbose)
705 {
706 s->EOL();
707 s->Indent();
708 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
709
710 s->Indent();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000711 s->Printf ("hit count = %-4u\n", GetHitCount());
712
713 if (m_options_ap.get())
714 {
Jim Ingham01363092010-06-18 01:00:58 +0000715 s->Indent();
716 m_options_ap->GetDescription (s, level);
717 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000718 }
719 s->IndentLess();
720 }
Jim Ingham1391cc72012-09-22 00:04:04 +0000721 else if (level != eDescriptionLevelInitial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000722 {
Jim Ingham01363092010-06-18 01:00:58 +0000723 s->Printf(", %sresolved, hit count = %u ",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000724 (IsResolved() ? "" : "un"),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000725 GetHitCount());
Jim Ingham01363092010-06-18 01:00:58 +0000726 if (m_options_ap.get())
727 {
728 m_options_ap->GetDescription (s, level);
729 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000730 }
731}
732
733void
734BreakpointLocation::Dump(Stream *s) const
735{
736 if (s == NULL)
737 return;
738
Daniel Malead01b2952012-11-29 21:49:15 +0000739 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 +0000740 "hw_index = %i hit_count = %-4u ignore_count = %-4u",
Johnny Chen9ec3c4f2012-01-26 00:08:14 +0000741 GetID(),
742 GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
743 (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()),
Johnny Chen50df1f92012-01-30 22:48:10 +0000744 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled",
Johnny Chen9ec3c4f2012-01-26 00:08:14 +0000745 IsHardware() ? "hardware" : "software",
746 GetHardwareIndex(),
747 GetHitCount(),
748 GetOptionsNoCreate()->GetIgnoreCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000749}
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000750
751void
752BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind)
753{
754 if (!m_being_created
755 && !m_owner.IsInternal()
756 && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
757 {
758 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind,
759 m_owner.shared_from_this());
760 data->GetBreakpointLocationCollection().Add (shared_from_this());
761 m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
762 }
763}
Jim Ingham77fd7382014-09-10 21:40:47 +0000764
765void
766BreakpointLocation::SwapLocation (BreakpointLocationSP swap_from)
767{
768 m_address = swap_from->m_address;
769 m_should_resolve_indirect_functions = swap_from->m_should_resolve_indirect_functions;
770 m_is_reexported = swap_from->m_is_reexported;
771 m_is_indirect = swap_from->m_is_indirect;
772 m_user_expression_sp.reset();
773}