blob: 9e8d9ea2789049e99387264f2ce86d6734b75045 [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"
Greg Clayton1f746072012-08-29 21:13:06 +000027#include "lldb/Symbol/CompileUnit.h"
28#include "lldb/Symbol/Symbol.h"
29#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
93bool
Johnny Chenfdad6792012-02-01 19:05:20 +000094BreakpointLocation::IsEnabled () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +000095{
Johnny Chen50df1f92012-01-30 22:48:10 +000096 if (!m_owner.IsEnabled())
97 return false;
98 else if (m_options_ap.get() != NULL)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000099 return m_options_ap->IsEnabled();
100 else
Johnny Chen50df1f92012-01-30 22:48:10 +0000101 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000102}
103
104void
105BreakpointLocation::SetEnabled (bool enabled)
106{
107 GetLocationOptions()->SetEnabled(enabled);
108 if (enabled)
109 {
110 ResolveBreakpointSite();
111 }
112 else
113 {
114 ClearBreakpointSite();
115 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000116 SendBreakpointLocationChangedEvent (enabled ? eBreakpointEventTypeEnabled : eBreakpointEventTypeDisabled);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000117}
118
119void
120BreakpointLocation::SetThreadID (lldb::tid_t thread_id)
121{
Jim Ingham1b54c882010-06-16 02:00:15 +0000122 if (thread_id != LLDB_INVALID_THREAD_ID)
123 GetLocationOptions()->SetThreadID(thread_id);
124 else
125 {
126 // If we're resetting this to an invalid thread id, then
127 // don't make an options pointer just to do that.
128 if (m_options_ap.get() != NULL)
129 m_options_ap->SetThreadID (thread_id);
130 }
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000131 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
132}
133
134lldb::tid_t
135BreakpointLocation::GetThreadID ()
136{
137 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
138 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID();
139 else
140 return LLDB_INVALID_THREAD_ID;
141}
142
143void
144BreakpointLocation::SetThreadIndex (uint32_t index)
145{
146 if (index != 0)
147 GetLocationOptions()->GetThreadSpec()->SetIndex(index);
148 else
149 {
150 // If we're resetting this to an invalid thread id, then
151 // don't make an options pointer just to do that.
152 if (m_options_ap.get() != NULL)
153 m_options_ap->GetThreadSpec()->SetIndex(index);
154 }
155 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
156
157}
158
159uint32_t
160BreakpointLocation::GetThreadIndex() const
161{
162 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
163 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetIndex();
164 else
165 return 0;
166}
167
168void
169BreakpointLocation::SetThreadName (const char *thread_name)
170{
171 if (thread_name != NULL)
172 GetLocationOptions()->GetThreadSpec()->SetName(thread_name);
173 else
174 {
175 // If we're resetting this to an invalid thread id, then
176 // don't make an options pointer just to do that.
177 if (m_options_ap.get() != NULL)
178 m_options_ap->GetThreadSpec()->SetName(thread_name);
179 }
180 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
181}
182
183const char *
184BreakpointLocation::GetThreadName () const
185{
186 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
187 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetName();
188 else
189 return NULL;
190}
191
192void
193BreakpointLocation::SetQueueName (const char *queue_name)
194{
195 if (queue_name != NULL)
196 GetLocationOptions()->GetThreadSpec()->SetQueueName(queue_name);
197 else
198 {
199 // If we're resetting this to an invalid thread id, then
200 // don't make an options pointer just to do that.
201 if (m_options_ap.get() != NULL)
202 m_options_ap->GetThreadSpec()->SetQueueName(queue_name);
203 }
204 SendBreakpointLocationChangedEvent (eBreakpointEventTypeThreadChanged);
205}
206
207const char *
208BreakpointLocation::GetQueueName () const
209{
210 if (GetOptionsNoCreate()->GetThreadSpecNoCreate())
211 return GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetQueueName();
212 else
213 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000214}
215
216bool
217BreakpointLocation::InvokeCallback (StoppointCallbackContext *context)
218{
Jim Ingham01363092010-06-18 01:00:58 +0000219 if (m_options_ap.get() != NULL && m_options_ap->HasCallback())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000220 return m_options_ap->InvokeCallback (context, m_owner.GetID(), GetID());
Jim Ingham01363092010-06-18 01:00:58 +0000221 else
222 return m_owner.InvokeCallback (context, GetID());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000223}
224
225void
226BreakpointLocation::SetCallback (BreakpointHitCallback callback, void *baton,
227 bool is_synchronous)
228{
229 // The default "Baton" class will keep a copy of "baton" and won't free
230 // or delete it when it goes goes out of scope.
231 GetLocationOptions()->SetCallback(callback, BatonSP (new Baton(baton)), is_synchronous);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000232 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000233}
234
235void
236BreakpointLocation::SetCallback (BreakpointHitCallback callback, const BatonSP &baton_sp,
237 bool is_synchronous)
238{
239 GetLocationOptions()->SetCallback (callback, baton_sp, is_synchronous);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000240 SendBreakpointLocationChangedEvent (eBreakpointEventTypeCommandChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000241}
242
Jim Ingham36f3b362010-10-14 23:45:03 +0000243
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000244void
245BreakpointLocation::ClearCallback ()
246{
247 GetLocationOptions()->ClearCallback();
248}
249
Jim Ingham36f3b362010-10-14 23:45:03 +0000250void
251BreakpointLocation::SetCondition (const char *condition)
252{
253 GetLocationOptions()->SetCondition (condition);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000254 SendBreakpointLocationChangedEvent (eBreakpointEventTypeConditionChanged);
Jim Ingham36f3b362010-10-14 23:45:03 +0000255}
256
Jim Ingham36f3b362010-10-14 23:45:03 +0000257const char *
Sean Callanan3dbf3462013-04-19 07:09:15 +0000258BreakpointLocation::GetConditionText (size_t *hash) const
Jim Ingham36f3b362010-10-14 23:45:03 +0000259{
Sean Callanan3dbf3462013-04-19 07:09:15 +0000260 return GetOptionsNoCreate()->GetConditionText(hash);
261}
262
263bool
264BreakpointLocation::ConditionSaysStop (ExecutionContext &exe_ctx, Error &error)
265{
266 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Sean Callananb4987e32013-06-06 20:18:50 +0000267
268 Mutex::Locker evaluation_locker(m_condition_mutex);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000269
270 size_t condition_hash;
271 const char *condition_text = GetConditionText(&condition_hash);
272
273 if (!condition_text)
Sean Callananec537a22013-05-10 21:58:45 +0000274 {
275 m_user_expression_sp.reset();
Sean Callanan3dbf3462013-04-19 07:09:15 +0000276 return false;
Sean Callananec537a22013-05-10 21:58:45 +0000277 }
Sean Callanan3dbf3462013-04-19 07:09:15 +0000278
279 if (condition_hash != m_condition_hash ||
280 !m_user_expression_sp ||
281 !m_user_expression_sp->MatchesContext(exe_ctx))
282 {
283 m_user_expression_sp.reset(new ClangUserExpression(condition_text,
284 NULL,
285 lldb::eLanguageTypeUnknown,
286 ClangUserExpression::eResultTypeAny));
287
288 StreamString errors;
289
290 if (!m_user_expression_sp->Parse(errors,
291 exe_ctx,
292 eExecutionPolicyOnlyWhenNeeded,
Greg Clayton23f8c952014-03-24 23:10:19 +0000293 true,
294 false))
Sean Callanan3dbf3462013-04-19 07:09:15 +0000295 {
296 error.SetErrorStringWithFormat("Couldn't parse conditional expression:\n%s",
297 errors.GetData());
298 m_user_expression_sp.reset();
299 return false;
300 }
301
302 m_condition_hash = condition_hash;
303 }
304
305 // We need to make sure the user sees any parse errors in their condition, so we'll hook the
306 // constructor errors up to the debugger's Async I/O.
307
308 ValueObjectSP result_value_sp;
Greg Clayton62afb9f2013-11-04 19:35:17 +0000309
310 EvaluateExpressionOptions options;
311 options.SetUnwindOnError(true);
312 options.SetIgnoreBreakpoints(true);
Jim Ingham6fbc48b2013-11-07 00:11:47 +0000313 options.SetTryAllThreads(true);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000314
315 Error expr_error;
316
317 StreamString execution_errors;
318
319 ClangExpressionVariableSP result_variable_sp;
320
Jim Ingham1624a2d2014-05-05 02:26:40 +0000321 ExpressionResults result_code =
Sean Callanan3dbf3462013-04-19 07:09:15 +0000322 m_user_expression_sp->Execute(execution_errors,
323 exe_ctx,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000324 options,
Sean Callanan3dbf3462013-04-19 07:09:15 +0000325 m_user_expression_sp,
Greg Clayton62afb9f2013-11-04 19:35:17 +0000326 result_variable_sp);
Sean Callanan3dbf3462013-04-19 07:09:15 +0000327
328 bool ret;
329
Jim Ingham8646d3c2014-05-05 02:47:44 +0000330 if (result_code == eExpressionCompleted)
Sean Callanan3dbf3462013-04-19 07:09:15 +0000331 {
Sean Callanan467441d52013-05-29 20:22:18 +0000332 if (!result_variable_sp)
333 {
Sean Callanan467441d52013-05-29 20:22:18 +0000334 error.SetErrorString("Expression did not return a result");
Sean Callanan879425f2013-06-24 17:58:46 +0000335 return false;
Sean Callanan467441d52013-05-29 20:22:18 +0000336 }
337
Sean Callanan3dbf3462013-04-19 07:09:15 +0000338 result_value_sp = result_variable_sp->GetValueObject();
339
340 if (result_value_sp)
341 {
342 Scalar scalar_value;
343 if (result_value_sp->ResolveValue (scalar_value))
344 {
345 if (scalar_value.ULongLong(1) == 0)
346 ret = false;
347 else
348 ret = true;
349 if (log)
350 log->Printf("Condition successfully evaluated, result is %s.\n",
351 ret ? "true" : "false");
352 }
353 else
354 {
355 ret = false;
356 error.SetErrorString("Failed to get an integer result from the expression");
357 }
358 }
359 else
360 {
361 ret = false;
362 error.SetErrorString("Failed to get any result from the expression");
363 }
364 }
365 else
366 {
367 ret = false;
368 error.SetErrorStringWithFormat("Couldn't execute expression:\n%s", execution_errors.GetData());
369 }
370
371 return ret;
Jim Ingham36f3b362010-10-14 23:45:03 +0000372}
373
Greg Claytonc982c762010-07-09 20:39:50 +0000374uint32_t
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000375BreakpointLocation::GetIgnoreCount ()
376{
Jim Ingham05407f62010-06-22 21:12:54 +0000377 return GetOptionsNoCreate()->GetIgnoreCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000378}
379
380void
Greg Claytonc982c762010-07-09 20:39:50 +0000381BreakpointLocation::SetIgnoreCount (uint32_t n)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000382{
383 GetLocationOptions()->SetIgnoreCount(n);
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000384 SendBreakpointLocationChangedEvent (eBreakpointEventTypeIgnoreChanged);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000385}
386
Jim Ingham0fd1b752012-06-26 22:27:55 +0000387void
388BreakpointLocation::DecrementIgnoreCount()
389{
390 if (m_options_ap.get() != NULL)
391 {
392 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
393 if (loc_ignore != 0)
394 m_options_ap->SetIgnoreCount(loc_ignore - 1);
395 }
396}
397
398bool
399BreakpointLocation::IgnoreCountShouldStop()
400{
401 if (m_options_ap.get() != NULL)
402 {
403 uint32_t loc_ignore = m_options_ap->GetIgnoreCount();
404 if (loc_ignore != 0)
405 {
406 m_owner.DecrementIgnoreCount();
407 DecrementIgnoreCount(); // Have to decrement our owners' ignore count, since it won't get a
408 // chance to.
409 return false;
410 }
411 }
412 return true;
413}
414
Jim Ingham1b54c882010-06-16 02:00:15 +0000415const BreakpointOptions *
Jim Ingham05407f62010-06-22 21:12:54 +0000416BreakpointLocation::GetOptionsNoCreate () const
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000417{
418 if (m_options_ap.get() != NULL)
419 return m_options_ap.get();
420 else
421 return m_owner.GetOptions ();
422}
423
424BreakpointOptions *
425BreakpointLocation::GetLocationOptions ()
426{
Jim Ingham01363092010-06-18 01:00:58 +0000427 // If we make the copy we don't copy the callbacks because that is potentially
428 // expensive and we don't want to do that for the simple case where someone is
429 // just disabling the location.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000430 if (m_options_ap.get() == NULL)
Jim Ingham01363092010-06-18 01:00:58 +0000431 m_options_ap.reset(BreakpointOptions::CopyOptionsNoCallback(*m_owner.GetOptions ()));
432
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000433 return m_options_ap.get();
434}
435
Jim Ingham1b54c882010-06-16 02:00:15 +0000436bool
437BreakpointLocation::ValidForThisThread (Thread *thread)
438{
Jim Ingham05407f62010-06-22 21:12:54 +0000439 return thread->MatchesSpec(GetOptionsNoCreate()->GetThreadSpecNoCreate());
Jim Ingham1b54c882010-06-16 02:00:15 +0000440}
441
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000442// RETURNS - true if we should stop at this breakpoint, false if we
Jim Ingham1b54c882010-06-16 02:00:15 +0000443// should continue. Note, we don't check the thread spec for the breakpoint
444// here, since if the breakpoint is not for this thread, then the event won't
445// even get reported, so the check is redundant.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000446
447bool
448BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
449{
450 bool should_stop = true;
Greg Clayton5160ce52013-03-27 23:08:40 +0000451 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000452
Jim Inghama672ece2014-10-22 01:54:17 +0000453 // Do this first, if a location is disabled, it shouldn't increment its hit count.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000454 if (!IsEnabled())
455 return false;
456
Jim Ingham0fd1b752012-06-26 22:27:55 +0000457 if (!IgnoreCountShouldStop())
458 return false;
459
460 if (!m_owner.IgnoreCountShouldStop())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000461 return false;
462
Jim Ingham36f3b362010-10-14 23:45:03 +0000463 // We only run synchronous callbacks in ShouldStop:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000464 context->is_synchronous = true;
465 should_stop = InvokeCallback (context);
Jim Ingham36f3b362010-10-14 23:45:03 +0000466
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000467 if (log)
Jim Ingham36f3b362010-10-14 23:45:03 +0000468 {
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000469 StreamString s;
470 GetDescription (&s, lldb::eDescriptionLevelVerbose);
471 log->Printf ("Hit breakpoint location: %s, %s.\n", s.GetData(), should_stop ? "stopping" : "continuing");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000472 }
Jim Ingham5b52f0c2011-06-02 23:58:26 +0000473
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000474 return should_stop;
475}
476
Jim Inghama672ece2014-10-22 01:54:17 +0000477void
478BreakpointLocation::BumpHitCount()
479{
480 if (IsEnabled())
Jim Inghamd762df82015-01-15 01:41:04 +0000481 {
482 // Step our hit count, and also step the hit count of the owner.
Jim Inghama672ece2014-10-22 01:54:17 +0000483 IncrementHitCount();
Jim Inghamd762df82015-01-15 01:41:04 +0000484 m_owner.IncrementHitCount();
485 }
486}
487
488void
489BreakpointLocation::UndoBumpHitCount()
490{
491 if (IsEnabled())
492 {
493 // Step our hit count, and also step the hit count of the owner.
494 DecrementHitCount();
495 m_owner.DecrementHitCount();
496 }
Jim Inghama672ece2014-10-22 01:54:17 +0000497}
498
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000499bool
500BreakpointLocation::IsResolved () const
501{
502 return m_bp_site_sp.get() != NULL;
503}
504
Jim Ingham36f3b362010-10-14 23:45:03 +0000505lldb::BreakpointSiteSP
506BreakpointLocation::GetBreakpointSite() const
507{
508 return m_bp_site_sp;
509}
510
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000511bool
512BreakpointLocation::ResolveBreakpointSite ()
513{
514 if (m_bp_site_sp)
515 return true;
516
Greg Claytonf5e56de2010-09-14 23:36:40 +0000517 Process *process = m_owner.GetTarget().GetProcessSP().get();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000518 if (process == NULL)
519 return false;
520
Greg Claytoneb023e72013-10-11 19:48:25 +0000521 lldb::break_id_t new_id = process->CreateBreakpointSite (shared_from_this(), m_owner.IsHardware());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000522
Stephen Wilson50bd94f2010-07-17 00:56:13 +0000523 if (new_id == LLDB_INVALID_BREAK_ID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000524 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000525 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000526 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000527 log->Warning ("Tried to add breakpoint site at 0x%" PRIx64 " but it was already present.\n",
Greg Claytonf3ef3d22011-05-22 22:46:53 +0000528 m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000529 return false;
530 }
531
532 return true;
533}
534
535bool
536BreakpointLocation::SetBreakpointSite (BreakpointSiteSP& bp_site_sp)
537{
538 m_bp_site_sp = bp_site_sp;
539 return true;
540}
541
542bool
543BreakpointLocation::ClearBreakpointSite ()
544{
545 if (m_bp_site_sp.get())
546 {
Jim Ingham15783132014-03-12 22:03:13 +0000547 ProcessSP process_sp(m_owner.GetTarget().GetProcessSP());
548 // If the process exists, get it to remove the owner, it will remove the physical implementation
549 // of the breakpoint as well if there are no more owners. Otherwise just remove this owner.
550 if (process_sp)
551 process_sp->RemoveOwnerFromBreakpointSite (GetBreakpoint().GetID(),
Jim Ingham01363092010-06-18 01:00:58 +0000552 GetID(), m_bp_site_sp);
Jim Ingham15783132014-03-12 22:03:13 +0000553 else
554 m_bp_site_sp->RemoveOwner(GetBreakpoint().GetID(), GetID());
555
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000556 m_bp_site_sp.reset();
557 return true;
558 }
559 return false;
560}
561
562void
563BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
564{
565 SymbolContext sc;
Jim Ingham1391cc72012-09-22 00:04:04 +0000566
567 // If the description level is "initial" then the breakpoint is printing out our initial state,
568 // and we should let it decide how it wants to print our label.
569 if (level != eDescriptionLevelInitial)
570 {
571 s->Indent();
572 BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
573 }
574
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000575 if (level == lldb::eDescriptionLevelBrief)
576 return;
577
Jim Ingham1391cc72012-09-22 00:04:04 +0000578 if (level != eDescriptionLevelInitial)
579 s->PutCString(": ");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000580
581 if (level == lldb::eDescriptionLevelVerbose)
582 s->IndentMore();
583
584 if (m_address.IsSectionOffset())
585 {
586 m_address.CalculateSymbolContext(&sc);
587
Jim Ingham1391cc72012-09-22 00:04:04 +0000588 if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000589 {
Jim Ingham1460e4b2014-01-10 23:46:59 +0000590 if (IsReExported())
591 s->PutCString ("re-exported target = ");
592 else
593 s->PutCString("where = ");
Jason Molendac980fa92015-02-13 23:24:21 +0000594 sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false, true, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000595 }
596 else
597 {
598 if (sc.module_sp)
599 {
600 s->EOL();
601 s->Indent("module = ");
602 sc.module_sp->GetFileSpec().Dump (s);
603 }
604
605 if (sc.comp_unit != NULL)
606 {
607 s->EOL();
608 s->Indent("compile unit = ");
Jim Ingham517b3b22010-10-27 22:58:34 +0000609 static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000610
611 if (sc.function != NULL)
612 {
613 s->EOL();
614 s->Indent("function = ");
615 s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>"));
616 }
617
618 if (sc.line_entry.line > 0)
619 {
620 s->EOL();
621 s->Indent("location = ");
Greg Clayton6dadd502010-09-02 21:44:10 +0000622 sc.line_entry.DumpStopContext (s, true);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000623 }
624
625 }
626 else
627 {
628 // If we don't have a comp unit, see if we have a symbol we can print.
629 if (sc.symbol)
630 {
631 s->EOL();
Jim Ingham1460e4b2014-01-10 23:46:59 +0000632 if (IsReExported())
633 s->Indent ("re-exported target = ");
634 else
635 s->Indent("symbol = ");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000636 s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>"));
637 }
638 }
639 }
640 }
641
642 if (level == lldb::eDescriptionLevelVerbose)
643 {
644 s->EOL();
645 s->Indent();
646 }
Jim Ingham1391cc72012-09-22 00:04:04 +0000647
648 if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
649 s->Printf (", ");
650 s->Printf ("address = ");
651
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000652 ExecutionContextScope *exe_scope = NULL;
653 Target *target = &m_owner.GetTarget();
654 if (target)
655 exe_scope = target->GetProcessSP().get();
656 if (exe_scope == NULL)
657 exe_scope = target;
658
Jim Ingham8f632662014-03-04 03:09:00 +0000659 if (level == eDescriptionLevelInitial)
Jim Ingham1391cc72012-09-22 00:04:04 +0000660 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
661 else
662 m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
Jim Ingham1460e4b2014-01-10 23:46:59 +0000663
664 if (IsIndirect() && m_bp_site_sp)
665 {
666 Address resolved_address;
667 resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
668 Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
669 if (resolved_symbol)
670 {
671 if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
672 s->Printf (", ");
673 else if (level == lldb::eDescriptionLevelVerbose)
674 {
675 s->EOL();
676 s->Indent();
677 }
678 s->Printf ("indirect target = %s", resolved_symbol->GetName().GetCString());
679 }
680 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000681
682 if (level == lldb::eDescriptionLevelVerbose)
683 {
684 s->EOL();
685 s->Indent();
686 s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");
687
688 s->Indent();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000689 s->Printf ("hit count = %-4u\n", GetHitCount());
690
691 if (m_options_ap.get())
692 {
Jim Ingham01363092010-06-18 01:00:58 +0000693 s->Indent();
694 m_options_ap->GetDescription (s, level);
695 s->EOL();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000696 }
697 s->IndentLess();
698 }
Jim Ingham1391cc72012-09-22 00:04:04 +0000699 else if (level != eDescriptionLevelInitial)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000700 {
Jim Ingham01363092010-06-18 01:00:58 +0000701 s->Printf(", %sresolved, hit count = %u ",
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000702 (IsResolved() ? "" : "un"),
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000703 GetHitCount());
Jim Ingham01363092010-06-18 01:00:58 +0000704 if (m_options_ap.get())
705 {
706 m_options_ap->GetDescription (s, level);
707 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000708 }
709}
710
711void
712BreakpointLocation::Dump(Stream *s) const
713{
714 if (s == NULL)
715 return;
716
Daniel Malead01b2952012-11-29 21:49:15 +0000717 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 +0000718 "hw_index = %i hit_count = %-4u ignore_count = %-4u",
Johnny Chen9ec3c4f2012-01-26 00:08:14 +0000719 GetID(),
720 GetOptionsNoCreate()->GetThreadSpecNoCreate()->GetTID(),
721 (uint64_t) m_address.GetOpcodeLoadAddress (&m_owner.GetTarget()),
Johnny Chen50df1f92012-01-30 22:48:10 +0000722 (m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled",
Johnny Chen9ec3c4f2012-01-26 00:08:14 +0000723 IsHardware() ? "hardware" : "software",
724 GetHardwareIndex(),
725 GetHitCount(),
726 GetOptionsNoCreate()->GetIgnoreCount());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000727}
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000728
729void
730BreakpointLocation::SendBreakpointLocationChangedEvent (lldb::BreakpointEventType eventKind)
731{
732 if (!m_being_created
733 && !m_owner.IsInternal()
734 && m_owner.GetTarget().EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged))
735 {
736 Breakpoint::BreakpointEventData *data = new Breakpoint::BreakpointEventData (eventKind,
737 m_owner.shared_from_this());
738 data->GetBreakpointLocationCollection().Add (shared_from_this());
739 m_owner.GetTarget().BroadcastEvent (Target::eBroadcastBitBreakpointChanged, data);
740 }
741}
Jim Ingham77fd7382014-09-10 21:40:47 +0000742
743void
744BreakpointLocation::SwapLocation (BreakpointLocationSP swap_from)
745{
746 m_address = swap_from->m_address;
747 m_should_resolve_indirect_functions = swap_from->m_should_resolve_indirect_functions;
748 m_is_reexported = swap_from->m_is_reexported;
749 m_is_indirect = swap_from->m_is_indirect;
750 m_user_expression_sp.reset();
751}