blob: 800ad0a277fcec64dbd4eb894ffe55fe9a878bbf [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- SBBreakpoint.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
Eugene Zelenkodbb0abb2015-10-31 01:22:59 +000010// C Includes
11// C++ Includes
12// Other libraries and framework includes
13// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014#include "lldb/API/SBBreakpoint.h"
15#include "lldb/API/SBBreakpointLocation.h"
16#include "lldb/API/SBDebugger.h"
Greg Clayton9fed0d82010-07-23 23:33:17 +000017#include "lldb/API/SBEvent.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include "lldb/API/SBProcess.h"
Caroline Ticedde9cff2010-09-20 05:20:02 +000019#include "lldb/API/SBStream.h"
Jim Ingham5e09c8c2014-12-16 23:40:14 +000020#include "lldb/API/SBStringList.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/API/SBThread.h"
22
23#include "lldb/Breakpoint/Breakpoint.h"
Jim Ingham01f16662016-09-14 19:07:35 +000024#include "lldb/Breakpoint/BreakpointIDList.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Breakpoint/BreakpointLocation.h"
26#include "lldb/Breakpoint/StoppointCallbackContext.h"
27#include "lldb/Core/Address.h"
Jim Inghamd80102e2014-04-02 01:04:55 +000028#include "lldb/Core/Debugger.h"
Caroline Ticeceb6b132010-10-26 03:11:13 +000029#include "lldb/Core/Log.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "lldb/Core/Stream.h"
31#include "lldb/Core/StreamFile.h"
Jim Inghamd80102e2014-04-02 01:04:55 +000032#include "lldb/Interpreter/CommandInterpreter.h"
33#include "lldb/Interpreter/ScriptInterpreter.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034#include "lldb/Target/Process.h"
Greg Claytond5944cd2013-12-06 01:12:00 +000035#include "lldb/Target/SectionLoadList.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036#include "lldb/Target/Target.h"
Jim Ingham62b02c62010-06-18 01:47:08 +000037#include "lldb/Target/Thread.h"
38#include "lldb/Target/ThreadSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039
Chris Lattner30fdc8d2010-06-08 16:52:24 +000040#include "lldb/lldb-enumerations.h"
41
Zachary Turner4e4fbe82016-09-13 17:53:38 +000042#include "llvm/ADT/STLExtras.h"
43
Chris Lattner30fdc8d2010-06-08 16:52:24 +000044using namespace lldb;
45using namespace lldb_private;
46
Kate Stoneb9c1b512016-09-06 20:57:50 +000047struct CallbackData {
48 SBBreakpoint::BreakpointHitCallback callback;
49 void *callback_baton;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050};
51
Zachary Turner4e4fbe82016-09-13 17:53:38 +000052class SBBreakpointCallbackBaton : public TypedBaton<CallbackData> {
Chris Lattner30fdc8d2010-06-08 16:52:24 +000053public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000054 SBBreakpointCallbackBaton(SBBreakpoint::BreakpointHitCallback callback,
55 void *baton)
Zachary Turner4e4fbe82016-09-13 17:53:38 +000056 : TypedBaton(llvm::make_unique<CallbackData>()) {
57 getItem()->callback = callback;
58 getItem()->callback_baton = baton;
Kate Stoneb9c1b512016-09-06 20:57:50 +000059 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060};
61
Kate Stoneb9c1b512016-09-06 20:57:50 +000062SBBreakpoint::SBBreakpoint() : m_opaque_sp() {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063
Kate Stoneb9c1b512016-09-06 20:57:50 +000064SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs)
65 : m_opaque_sp(rhs.m_opaque_sp) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066
Kate Stoneb9c1b512016-09-06 20:57:50 +000067SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP &bp_sp)
68 : m_opaque_sp(bp_sp) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000069
Eugene Zelenkodbb0abb2015-10-31 01:22:59 +000070SBBreakpoint::~SBBreakpoint() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000071
Kate Stoneb9c1b512016-09-06 20:57:50 +000072const SBBreakpoint &SBBreakpoint::operator=(const SBBreakpoint &rhs) {
73 if (this != &rhs)
74 m_opaque_sp = rhs.m_opaque_sp;
75 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000076}
77
Kate Stoneb9c1b512016-09-06 20:57:50 +000078bool SBBreakpoint::operator==(const lldb::SBBreakpoint &rhs) {
79 if (m_opaque_sp && rhs.m_opaque_sp)
80 return m_opaque_sp.get() == rhs.m_opaque_sp.get();
81 return false;
82}
83
84bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) {
85 if (m_opaque_sp && rhs.m_opaque_sp)
86 return m_opaque_sp.get() != rhs.m_opaque_sp.get();
87 return (m_opaque_sp && !rhs.m_opaque_sp) || (rhs.m_opaque_sp && !m_opaque_sp);
88}
89
90break_id_t SBBreakpoint::GetID() const {
91 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
92
93 break_id_t break_id = LLDB_INVALID_BREAK_ID;
94 if (m_opaque_sp)
95 break_id = m_opaque_sp->GetID();
96
97 if (log) {
98 if (break_id == LLDB_INVALID_BREAK_ID)
99 log->Printf("SBBreakpoint(%p)::GetID () => LLDB_INVALID_BREAK_ID",
100 static_cast<void *>(m_opaque_sp.get()));
101 else
102 log->Printf("SBBreakpoint(%p)::GetID () => %u",
103 static_cast<void *>(m_opaque_sp.get()), break_id);
104 }
105
106 return break_id;
107}
108
109bool SBBreakpoint::IsValid() const {
110 if (!m_opaque_sp)
111 return false;
112 else if (m_opaque_sp->GetTarget().GetBreakpointByID(m_opaque_sp->GetID()))
113 return true;
114 else
Greg Claytonac2eb9b2010-12-12 19:25:26 +0000115 return false;
116}
117
Kate Stoneb9c1b512016-09-06 20:57:50 +0000118void SBBreakpoint::ClearAllBreakpointSites() {
119 if (m_opaque_sp) {
120 std::lock_guard<std::recursive_mutex> guard(
121 m_opaque_sp->GetTarget().GetAPIMutex());
122 m_opaque_sp->ClearAllBreakpointSites();
123 }
Enrico Granatac3387332013-05-03 01:29:27 +0000124}
125
Kate Stoneb9c1b512016-09-06 20:57:50 +0000126SBBreakpointLocation SBBreakpoint::FindLocationByAddress(addr_t vm_addr) {
127 SBBreakpointLocation sb_bp_location;
Caroline Ticeceb6b132010-10-26 03:11:13 +0000128
Kate Stoneb9c1b512016-09-06 20:57:50 +0000129 if (m_opaque_sp) {
130 if (vm_addr != LLDB_INVALID_ADDRESS) {
131 std::lock_guard<std::recursive_mutex> guard(
132 m_opaque_sp->GetTarget().GetAPIMutex());
133 Address address;
134 Target &target = m_opaque_sp->GetTarget();
135 if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
136 address.SetRawAddress(vm_addr);
137 }
138 sb_bp_location.SetLocation(m_opaque_sp->FindLocationByAddress(address));
Greg Claytonaf67cec2010-12-20 20:49:23 +0000139 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000140 }
141 return sb_bp_location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000142}
143
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144break_id_t SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr) {
145 break_id_t break_id = LLDB_INVALID_BREAK_ID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000146
Kate Stoneb9c1b512016-09-06 20:57:50 +0000147 if (m_opaque_sp && vm_addr != LLDB_INVALID_ADDRESS) {
148 std::lock_guard<std::recursive_mutex> guard(
149 m_opaque_sp->GetTarget().GetAPIMutex());
150 Address address;
151 Target &target = m_opaque_sp->GetTarget();
152 if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
153 address.SetRawAddress(vm_addr);
Greg Claytonaf67cec2010-12-20 20:49:23 +0000154 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000155 break_id = m_opaque_sp->FindLocationIDByAddress(address);
156 }
157
158 return break_id;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000159}
160
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161SBBreakpointLocation SBBreakpoint::FindLocationByID(break_id_t bp_loc_id) {
162 SBBreakpointLocation sb_bp_location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000163
Kate Stoneb9c1b512016-09-06 20:57:50 +0000164 if (m_opaque_sp) {
165 std::lock_guard<std::recursive_mutex> guard(
166 m_opaque_sp->GetTarget().GetAPIMutex());
167 sb_bp_location.SetLocation(m_opaque_sp->FindLocationByID(bp_loc_id));
168 }
169
170 return sb_bp_location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000171}
172
Kate Stoneb9c1b512016-09-06 20:57:50 +0000173SBBreakpointLocation SBBreakpoint::GetLocationAtIndex(uint32_t index) {
174 SBBreakpointLocation sb_bp_location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000175
Kate Stoneb9c1b512016-09-06 20:57:50 +0000176 if (m_opaque_sp) {
177 std::lock_guard<std::recursive_mutex> guard(
178 m_opaque_sp->GetTarget().GetAPIMutex());
179 sb_bp_location.SetLocation(m_opaque_sp->GetLocationAtIndex(index));
180 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000181
Kate Stoneb9c1b512016-09-06 20:57:50 +0000182 return sb_bp_location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000183}
184
Kate Stoneb9c1b512016-09-06 20:57:50 +0000185void SBBreakpoint::SetEnabled(bool enable) {
186 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000187
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188 if (log)
189 log->Printf("SBBreakpoint(%p)::SetEnabled (enabled=%i)",
190 static_cast<void *>(m_opaque_sp.get()), enable);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000191
Kate Stoneb9c1b512016-09-06 20:57:50 +0000192 if (m_opaque_sp) {
193 std::lock_guard<std::recursive_mutex> guard(
194 m_opaque_sp->GetTarget().GetAPIMutex());
195 m_opaque_sp->SetEnabled(enable);
196 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000197}
198
Kate Stoneb9c1b512016-09-06 20:57:50 +0000199bool SBBreakpoint::IsEnabled() {
200 if (m_opaque_sp) {
201 std::lock_guard<std::recursive_mutex> guard(
202 m_opaque_sp->GetTarget().GetAPIMutex());
203 return m_opaque_sp->IsEnabled();
204 } else
Greg Clayton05faeb72010-10-07 04:19:01 +0000205 return false;
Caroline Ticedde9cff2010-09-20 05:20:02 +0000206}
207
Kate Stoneb9c1b512016-09-06 20:57:50 +0000208void SBBreakpoint::SetOneShot(bool one_shot) {
209 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000210
Kate Stoneb9c1b512016-09-06 20:57:50 +0000211 if (log)
212 log->Printf("SBBreakpoint(%p)::SetOneShot (one_shot=%i)",
213 static_cast<void *>(m_opaque_sp.get()), one_shot);
214
215 if (m_opaque_sp) {
216 std::lock_guard<std::recursive_mutex> guard(
217 m_opaque_sp->GetTarget().GetAPIMutex());
218 m_opaque_sp->SetOneShot(one_shot);
219 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000220}
221
Kate Stoneb9c1b512016-09-06 20:57:50 +0000222bool SBBreakpoint::IsOneShot() const {
223 if (m_opaque_sp) {
224 std::lock_guard<std::recursive_mutex> guard(
225 m_opaque_sp->GetTarget().GetAPIMutex());
226 return m_opaque_sp->IsOneShot();
227 } else
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000228 return false;
229}
230
Kate Stoneb9c1b512016-09-06 20:57:50 +0000231bool SBBreakpoint::IsInternal() {
232 if (m_opaque_sp) {
233 std::lock_guard<std::recursive_mutex> guard(
234 m_opaque_sp->GetTarget().GetAPIMutex());
235 return m_opaque_sp->IsInternal();
236 } else
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000237 return false;
238}
239
Kate Stoneb9c1b512016-09-06 20:57:50 +0000240void SBBreakpoint::SetIgnoreCount(uint32_t count) {
241 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000242
Kate Stoneb9c1b512016-09-06 20:57:50 +0000243 if (log)
244 log->Printf("SBBreakpoint(%p)::SetIgnoreCount (count=%u)",
245 static_cast<void *>(m_opaque_sp.get()), count);
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000246
Kate Stoneb9c1b512016-09-06 20:57:50 +0000247 if (m_opaque_sp) {
248 std::lock_guard<std::recursive_mutex> guard(
249 m_opaque_sp->GetTarget().GetAPIMutex());
250 m_opaque_sp->SetIgnoreCount(count);
251 }
252}
253
254void SBBreakpoint::SetCondition(const char *condition) {
255 if (m_opaque_sp) {
256 std::lock_guard<std::recursive_mutex> guard(
257 m_opaque_sp->GetTarget().GetAPIMutex());
258 m_opaque_sp->SetCondition(condition);
259 }
260}
261
262const char *SBBreakpoint::GetCondition() {
263 if (m_opaque_sp) {
264 std::lock_guard<std::recursive_mutex> guard(
265 m_opaque_sp->GetTarget().GetAPIMutex());
266 return m_opaque_sp->GetConditionText();
267 }
268 return nullptr;
269}
270
271uint32_t SBBreakpoint::GetHitCount() const {
272 uint32_t count = 0;
273 if (m_opaque_sp) {
274 std::lock_guard<std::recursive_mutex> guard(
275 m_opaque_sp->GetTarget().GetAPIMutex());
276 count = m_opaque_sp->GetHitCount();
277 }
278
279 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
280 if (log)
281 log->Printf("SBBreakpoint(%p)::GetHitCount () => %u",
282 static_cast<void *>(m_opaque_sp.get()), count);
283
284 return count;
285}
286
287uint32_t SBBreakpoint::GetIgnoreCount() const {
288 uint32_t count = 0;
289 if (m_opaque_sp) {
290 std::lock_guard<std::recursive_mutex> guard(
291 m_opaque_sp->GetTarget().GetAPIMutex());
292 count = m_opaque_sp->GetIgnoreCount();
293 }
294
295 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
296 if (log)
297 log->Printf("SBBreakpoint(%p)::GetIgnoreCount () => %u",
298 static_cast<void *>(m_opaque_sp.get()), count);
299
300 return count;
301}
302
303void SBBreakpoint::SetThreadID(tid_t tid) {
304 if (m_opaque_sp) {
305 std::lock_guard<std::recursive_mutex> guard(
306 m_opaque_sp->GetTarget().GetAPIMutex());
307 m_opaque_sp->SetThreadID(tid);
308 }
309 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
310 if (log)
311 log->Printf("SBBreakpoint(%p)::SetThreadID (tid=0x%4.4" PRIx64 ")",
312 static_cast<void *>(m_opaque_sp.get()), tid);
313}
314
315tid_t SBBreakpoint::GetThreadID() {
316 tid_t tid = LLDB_INVALID_THREAD_ID;
317 if (m_opaque_sp) {
318 std::lock_guard<std::recursive_mutex> guard(
319 m_opaque_sp->GetTarget().GetAPIMutex());
320 tid = m_opaque_sp->GetThreadID();
321 }
322
323 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
324 if (log)
325 log->Printf("SBBreakpoint(%p)::GetThreadID () => 0x%4.4" PRIx64,
326 static_cast<void *>(m_opaque_sp.get()), tid);
327 return tid;
328}
329
330void SBBreakpoint::SetThreadIndex(uint32_t index) {
331 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
332 if (log)
333 log->Printf("SBBreakpoint(%p)::SetThreadIndex (%u)",
334 static_cast<void *>(m_opaque_sp.get()), index);
335 if (m_opaque_sp) {
336 std::lock_guard<std::recursive_mutex> guard(
337 m_opaque_sp->GetTarget().GetAPIMutex());
338 m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex(index);
339 }
340}
341
342uint32_t SBBreakpoint::GetThreadIndex() const {
343 uint32_t thread_idx = UINT32_MAX;
344 if (m_opaque_sp) {
345 std::lock_guard<std::recursive_mutex> guard(
346 m_opaque_sp->GetTarget().GetAPIMutex());
347 const ThreadSpec *thread_spec =
348 m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
349 if (thread_spec != nullptr)
350 thread_idx = thread_spec->GetIndex();
351 }
352 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
353 if (log)
354 log->Printf("SBBreakpoint(%p)::GetThreadIndex () => %u",
355 static_cast<void *>(m_opaque_sp.get()), thread_idx);
356
357 return thread_idx;
358}
359
360void SBBreakpoint::SetThreadName(const char *thread_name) {
361 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
362 if (log)
363 log->Printf("SBBreakpoint(%p)::SetThreadName (%s)",
364 static_cast<void *>(m_opaque_sp.get()), thread_name);
365
366 if (m_opaque_sp) {
367 std::lock_guard<std::recursive_mutex> guard(
368 m_opaque_sp->GetTarget().GetAPIMutex());
369 m_opaque_sp->GetOptions()->GetThreadSpec()->SetName(thread_name);
370 }
371}
372
373const char *SBBreakpoint::GetThreadName() const {
374 const char *name = nullptr;
375 if (m_opaque_sp) {
376 std::lock_guard<std::recursive_mutex> guard(
377 m_opaque_sp->GetTarget().GetAPIMutex());
378 const ThreadSpec *thread_spec =
379 m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
380 if (thread_spec != nullptr)
381 name = thread_spec->GetName();
382 }
383 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
384 if (log)
385 log->Printf("SBBreakpoint(%p)::GetThreadName () => %s",
386 static_cast<void *>(m_opaque_sp.get()), name);
387
388 return name;
389}
390
391void SBBreakpoint::SetQueueName(const char *queue_name) {
392 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
393 if (log)
394 log->Printf("SBBreakpoint(%p)::SetQueueName (%s)",
395 static_cast<void *>(m_opaque_sp.get()), queue_name);
396 if (m_opaque_sp) {
397 std::lock_guard<std::recursive_mutex> guard(
398 m_opaque_sp->GetTarget().GetAPIMutex());
399 m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName(queue_name);
400 }
401}
402
403const char *SBBreakpoint::GetQueueName() const {
404 const char *name = nullptr;
405 if (m_opaque_sp) {
406 std::lock_guard<std::recursive_mutex> guard(
407 m_opaque_sp->GetTarget().GetAPIMutex());
408 const ThreadSpec *thread_spec =
409 m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
410 if (thread_spec)
411 name = thread_spec->GetQueueName();
412 }
413 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
414 if (log)
415 log->Printf("SBBreakpoint(%p)::GetQueueName () => %s",
416 static_cast<void *>(m_opaque_sp.get()), name);
417
418 return name;
419}
420
421size_t SBBreakpoint::GetNumResolvedLocations() const {
422 size_t num_resolved = 0;
423 if (m_opaque_sp) {
424 std::lock_guard<std::recursive_mutex> guard(
425 m_opaque_sp->GetTarget().GetAPIMutex());
426 num_resolved = m_opaque_sp->GetNumResolvedLocations();
427 }
428 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
429 if (log)
430 log->Printf("SBBreakpoint(%p)::GetNumResolvedLocations () => %" PRIu64,
431 static_cast<void *>(m_opaque_sp.get()),
432 static_cast<uint64_t>(num_resolved));
433 return num_resolved;
434}
435
436size_t SBBreakpoint::GetNumLocations() const {
437 size_t num_locs = 0;
438 if (m_opaque_sp) {
439 std::lock_guard<std::recursive_mutex> guard(
440 m_opaque_sp->GetTarget().GetAPIMutex());
441 num_locs = m_opaque_sp->GetNumLocations();
442 }
443 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
444 if (log)
445 log->Printf("SBBreakpoint(%p)::GetNumLocations () => %" PRIu64,
446 static_cast<void *>(m_opaque_sp.get()),
447 static_cast<uint64_t>(num_locs));
448 return num_locs;
449}
450
451bool SBBreakpoint::GetDescription(SBStream &s) {
452 if (m_opaque_sp) {
453 std::lock_guard<std::recursive_mutex> guard(
454 m_opaque_sp->GetTarget().GetAPIMutex());
455 s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID());
456 m_opaque_sp->GetResolverDescription(s.get());
457 m_opaque_sp->GetFilterDescription(s.get());
458 const size_t num_locations = m_opaque_sp->GetNumLocations();
459 s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
460 return true;
461 }
462 s.Printf("No value");
463 return false;
464}
465
466bool SBBreakpoint::PrivateBreakpointHitCallback(void *baton,
467 StoppointCallbackContext *ctx,
468 lldb::user_id_t break_id,
469 lldb::user_id_t break_loc_id) {
470 ExecutionContext exe_ctx(ctx->exe_ctx_ref);
471 BreakpointSP bp_sp(
472 exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
473 if (baton && bp_sp) {
474 CallbackData *data = (CallbackData *)baton;
475 lldb_private::Breakpoint *bp = bp_sp.get();
476 if (bp && data->callback) {
477 Process *process = exe_ctx.GetProcessPtr();
478 if (process) {
479 SBProcess sb_process(process->shared_from_this());
480 SBThread sb_thread;
481 SBBreakpointLocation sb_location;
482 assert(bp_sp);
483 sb_location.SetLocation(bp_sp->FindLocationByID(break_loc_id));
484 Thread *thread = exe_ctx.GetThreadPtr();
485 if (thread)
486 sb_thread.SetThread(thread->shared_from_this());
487
488 return data->callback(data->callback_baton, sb_process, sb_thread,
489 sb_location);
490 }
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000491 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000492 }
493 return true; // Return true if we should stop at this breakpoint
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000494}
495
Kate Stoneb9c1b512016-09-06 20:57:50 +0000496void SBBreakpoint::SetCallback(BreakpointHitCallback callback, void *baton) {
497 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
498
499 if (log) {
500 void *pointer = &callback;
501 log->Printf("SBBreakpoint(%p)::SetCallback (callback=%p, baton=%p)",
502 static_cast<void *>(m_opaque_sp.get()),
503 *static_cast<void **>(&pointer), static_cast<void *>(baton));
504 }
505
506 if (m_opaque_sp) {
507 std::lock_guard<std::recursive_mutex> guard(
508 m_opaque_sp->GetTarget().GetAPIMutex());
509 BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
510 m_opaque_sp->SetCallback(SBBreakpoint::PrivateBreakpointHitCallback,
511 baton_sp, false);
512 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000513}
514
Kate Stoneb9c1b512016-09-06 20:57:50 +0000515void SBBreakpoint::SetScriptCallbackFunction(
516 const char *callback_function_name) {
517 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
518
519 if (log)
520 log->Printf("SBBreakpoint(%p)::SetScriptCallbackFunction (callback=%s)",
521 static_cast<void *>(m_opaque_sp.get()), callback_function_name);
522
523 if (m_opaque_sp) {
524 std::lock_guard<std::recursive_mutex> guard(
525 m_opaque_sp->GetTarget().GetAPIMutex());
526 BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
527 m_opaque_sp->GetTarget()
528 .GetDebugger()
529 .GetCommandInterpreter()
530 .GetScriptInterpreter()
531 ->SetBreakpointCommandCallbackFunction(bp_options,
532 callback_function_name);
533 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000534}
535
Kate Stoneb9c1b512016-09-06 20:57:50 +0000536SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) {
537 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
538
539 if (log)
540 log->Printf("SBBreakpoint(%p)::SetScriptCallbackBody: callback body:\n%s)",
541 static_cast<void *>(m_opaque_sp.get()), callback_body_text);
542
543 SBError sb_error;
544 if (m_opaque_sp) {
545 std::lock_guard<std::recursive_mutex> guard(
546 m_opaque_sp->GetTarget().GetAPIMutex());
547 BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
548 Error error =
549 m_opaque_sp->GetTarget()
550 .GetDebugger()
551 .GetCommandInterpreter()
552 .GetScriptInterpreter()
553 ->SetBreakpointCommandCallback(bp_options, callback_body_text);
554 sb_error.SetError(error);
555 } else
556 sb_error.SetErrorString("invalid breakpoint");
557
558 return sb_error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000559}
560
Kate Stoneb9c1b512016-09-06 20:57:50 +0000561bool SBBreakpoint::AddName(const char *new_name) {
562 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
563
564 if (log)
565 log->Printf("SBBreakpoint(%p)::AddName (name=%s)",
566 static_cast<void *>(m_opaque_sp.get()), new_name);
567
568 if (m_opaque_sp) {
569 std::lock_guard<std::recursive_mutex> guard(
570 m_opaque_sp->GetTarget().GetAPIMutex());
571 Error error; // Think I'm just going to swallow the error here, it's
572 // probably more annoying to have to provide it.
573 return m_opaque_sp->AddName(new_name, error);
574 }
575
576 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000577}
578
Kate Stoneb9c1b512016-09-06 20:57:50 +0000579void SBBreakpoint::RemoveName(const char *name_to_remove) {
580 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
581
582 if (log)
583 log->Printf("SBBreakpoint(%p)::RemoveName (name=%s)",
584 static_cast<void *>(m_opaque_sp.get()), name_to_remove);
585
586 if (m_opaque_sp) {
587 std::lock_guard<std::recursive_mutex> guard(
588 m_opaque_sp->GetTarget().GetAPIMutex());
589 m_opaque_sp->RemoveName(name_to_remove);
590 }
591}
592
593bool SBBreakpoint::MatchesName(const char *name) {
594 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
595
596 if (log)
597 log->Printf("SBBreakpoint(%p)::MatchesName (name=%s)",
598 static_cast<void *>(m_opaque_sp.get()), name);
599
600 if (m_opaque_sp) {
601 std::lock_guard<std::recursive_mutex> guard(
602 m_opaque_sp->GetTarget().GetAPIMutex());
603 return m_opaque_sp->MatchesName(name);
604 }
605
606 return false;
607}
608
609void SBBreakpoint::GetNames(SBStringList &names) {
610 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
611
612 if (log)
613 log->Printf("SBBreakpoint(%p)::GetNames ()",
614 static_cast<void *>(m_opaque_sp.get()));
615
616 if (m_opaque_sp) {
617 std::lock_guard<std::recursive_mutex> guard(
618 m_opaque_sp->GetTarget().GetAPIMutex());
619 std::vector<std::string> names_vec;
620 m_opaque_sp->GetNames(names_vec);
621 for (std::string name : names_vec) {
622 names.AppendString(name.c_str());
623 }
624 }
625}
626
627lldb_private::Breakpoint *SBBreakpoint::operator->() const {
628 return m_opaque_sp.get();
629}
630
631lldb_private::Breakpoint *SBBreakpoint::get() const {
632 return m_opaque_sp.get();
633}
634
635lldb::BreakpointSP &SBBreakpoint::operator*() { return m_opaque_sp; }
636
637const lldb::BreakpointSP &SBBreakpoint::operator*() const {
638 return m_opaque_sp;
639}
640
641bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) {
642 return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) !=
643 nullptr;
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000644}
645
Greg Clayton9fed0d82010-07-23 23:33:17 +0000646BreakpointEventType
Kate Stoneb9c1b512016-09-06 20:57:50 +0000647SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) {
648 if (event.IsValid())
649 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
650 event.GetSP());
651 return eBreakpointEventTypeInvalidType;
Greg Clayton9fed0d82010-07-23 23:33:17 +0000652}
653
Kate Stoneb9c1b512016-09-06 20:57:50 +0000654SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) {
655 SBBreakpoint sb_breakpoint;
656 if (event.IsValid())
657 sb_breakpoint.m_opaque_sp =
658 Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event.GetSP());
659 return sb_breakpoint;
Greg Clayton9fed0d82010-07-23 23:33:17 +0000660}
661
662SBBreakpointLocation
Kate Stoneb9c1b512016-09-06 20:57:50 +0000663SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event,
664 uint32_t loc_idx) {
665 SBBreakpointLocation sb_breakpoint_loc;
666 if (event.IsValid())
667 sb_breakpoint_loc.SetLocation(
668 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent(
669 event.GetSP(), loc_idx));
670 return sb_breakpoint_loc;
Greg Clayton9fed0d82010-07-23 23:33:17 +0000671}
672
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000673uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000674SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) {
675 uint32_t num_locations = 0;
676 if (event.IsValid())
677 num_locations =
678 (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
679 event.GetSP()));
680 return num_locations;
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000681}
Jim Ingham01f16662016-09-14 19:07:35 +0000682
683// This is simple collection of breakpoint id's and their target.
684class lldb::SBBreakpointListImpl {
685public:
686 SBBreakpointListImpl(SBTarget &target) : m_target_wp() {
687 if (target.IsValid())
688 m_target_wp = target.GetSP();
689 }
690
691 ~SBBreakpointListImpl() = default;
692
693 size_t GetSize() { return m_break_ids.size(); }
694
695 BreakpointSP GetBreakpointAtIndex(size_t idx) {
696 if (idx >= m_break_ids.size())
697 return BreakpointSP();
698 TargetSP target_sp = m_target_wp.lock();
699 if (!target_sp)
700 return BreakpointSP();
701 lldb::break_id_t bp_id = m_break_ids[idx];
702 return target_sp->GetBreakpointList().FindBreakpointByID(bp_id);
703 }
704
705 bool Append(Breakpoint &bkpt) {
706 TargetSP target_sp = m_target_wp.lock();
707 if (!target_sp)
708 return false;
709 if (bkpt.GetTargetSP() != target_sp)
710 return false;
711 m_break_ids.push_back(bkpt.GetID());
712 return true;
713 }
714
715 bool AppendIfUnique(Breakpoint &bkpt) {
716 TargetSP target_sp = m_target_wp.lock();
717 if (!target_sp)
718 return false;
719 if (bkpt.GetTargetSP() != target_sp)
720 return false;
721 lldb::break_id_t bp_id = bkpt.GetID();
722 if (find(m_break_ids.begin(), m_break_ids.end(), bp_id) ==
723 m_break_ids.end())
724 return false;
725
726 m_break_ids.push_back(bkpt.GetID());
727 return true;
728 }
729
730 bool AppendByID(lldb::break_id_t id) {
731 TargetSP target_sp = m_target_wp.lock();
732 if (!target_sp)
733 return false;
734 if (id == LLDB_INVALID_BREAK_ID)
735 return false;
736 m_break_ids.push_back(id);
737 return true;
738 }
739
740 void Clear() { m_break_ids.clear(); }
741
742 void CopyToBreakpointIDList(lldb_private::BreakpointIDList &bp_list) {
743 for (lldb::break_id_t id : m_break_ids) {
744 bp_list.AddBreakpointID(BreakpointID(id));
745 }
746 }
747
748 TargetSP GetTarget() { return m_target_wp.lock(); }
749
750private:
751 std::vector<lldb::break_id_t> m_break_ids;
752 TargetWP m_target_wp;
753};
754
755SBBreakpointList::SBBreakpointList(SBTarget &target)
756 : m_opaque_sp(new lldb::SBBreakpointListImpl(target)) {}
757
758SBBreakpointList::~SBBreakpointList() {}
759
760size_t SBBreakpointList::GetSize() const {
761 if (!m_opaque_sp)
762 return 0;
763 else
764 return m_opaque_sp->GetSize();
765}
766
767SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) {
768 if (!m_opaque_sp)
769 return SBBreakpoint();
770
771 BreakpointSP bkpt_sp = m_opaque_sp->GetBreakpointAtIndex(idx);
772 return SBBreakpoint(bkpt_sp);
773}
774
775void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) {
776 if (!sb_bkpt.IsValid())
777 return;
778 if (!m_opaque_sp)
779 return;
780 m_opaque_sp->Append(*sb_bkpt.get());
781}
782
783void SBBreakpointList::AppendByID(lldb::break_id_t id) {
784 if (!m_opaque_sp)
785 return;
786 m_opaque_sp->AppendByID(id);
787}
788
789bool SBBreakpointList::AppendIfUnique(const SBBreakpoint &sb_bkpt) {
790 if (!sb_bkpt.IsValid())
791 return false;
792 if (!m_opaque_sp)
793 return false;
794 return m_opaque_sp->AppendIfUnique(*sb_bkpt.get());
795}
796
797void SBBreakpointList::Clear() {
798 if (m_opaque_sp)
799 m_opaque_sp->Clear();
800}
801
802void SBBreakpointList::CopyToBreakpointIDList(
803 lldb_private::BreakpointIDList &bp_id_list) {
804 if (m_opaque_sp)
805 m_opaque_sp->CopyToBreakpointIDList(bp_id_list);
806}