blob: bbdb23766cc4f078b9b4f86bfcf8dfaa758b5634 [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"
24#include "lldb/Breakpoint/BreakpointLocation.h"
25#include "lldb/Breakpoint/StoppointCallbackContext.h"
26#include "lldb/Core/Address.h"
Jim Inghamd80102e2014-04-02 01:04:55 +000027#include "lldb/Core/Debugger.h"
Caroline Ticeceb6b132010-10-26 03:11:13 +000028#include "lldb/Core/Log.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Core/Stream.h"
30#include "lldb/Core/StreamFile.h"
Jim Inghamd80102e2014-04-02 01:04:55 +000031#include "lldb/Interpreter/CommandInterpreter.h"
32#include "lldb/Interpreter/ScriptInterpreter.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033#include "lldb/Target/Process.h"
Greg Claytond5944cd2013-12-06 01:12:00 +000034#include "lldb/Target/SectionLoadList.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035#include "lldb/Target/Target.h"
Jim Ingham62b02c62010-06-18 01:47:08 +000036#include "lldb/Target/Thread.h"
37#include "lldb/Target/ThreadSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000038
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039#include "lldb/lldb-enumerations.h"
40
Zachary Turner4e4fbe82016-09-13 17:53:38 +000041#include "llvm/ADT/STLExtras.h"
42
Chris Lattner30fdc8d2010-06-08 16:52:24 +000043using namespace lldb;
44using namespace lldb_private;
45
Kate Stoneb9c1b512016-09-06 20:57:50 +000046struct CallbackData {
47 SBBreakpoint::BreakpointHitCallback callback;
48 void *callback_baton;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049};
50
Zachary Turner4e4fbe82016-09-13 17:53:38 +000051class SBBreakpointCallbackBaton : public TypedBaton<CallbackData> {
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000053 SBBreakpointCallbackBaton(SBBreakpoint::BreakpointHitCallback callback,
54 void *baton)
Zachary Turner4e4fbe82016-09-13 17:53:38 +000055 : TypedBaton(llvm::make_unique<CallbackData>()) {
56 getItem()->callback = callback;
57 getItem()->callback_baton = baton;
Kate Stoneb9c1b512016-09-06 20:57:50 +000058 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +000059};
60
Kate Stoneb9c1b512016-09-06 20:57:50 +000061SBBreakpoint::SBBreakpoint() : m_opaque_sp() {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000062
Kate Stoneb9c1b512016-09-06 20:57:50 +000063SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs)
64 : m_opaque_sp(rhs.m_opaque_sp) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000065
Kate Stoneb9c1b512016-09-06 20:57:50 +000066SBBreakpoint::SBBreakpoint(const lldb::BreakpointSP &bp_sp)
67 : m_opaque_sp(bp_sp) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000068
Eugene Zelenkodbb0abb2015-10-31 01:22:59 +000069SBBreakpoint::~SBBreakpoint() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000070
Kate Stoneb9c1b512016-09-06 20:57:50 +000071const SBBreakpoint &SBBreakpoint::operator=(const SBBreakpoint &rhs) {
72 if (this != &rhs)
73 m_opaque_sp = rhs.m_opaque_sp;
74 return *this;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000075}
76
Kate Stoneb9c1b512016-09-06 20:57:50 +000077bool SBBreakpoint::operator==(const lldb::SBBreakpoint &rhs) {
78 if (m_opaque_sp && rhs.m_opaque_sp)
79 return m_opaque_sp.get() == rhs.m_opaque_sp.get();
80 return false;
81}
82
83bool SBBreakpoint::operator!=(const lldb::SBBreakpoint &rhs) {
84 if (m_opaque_sp && rhs.m_opaque_sp)
85 return m_opaque_sp.get() != rhs.m_opaque_sp.get();
86 return (m_opaque_sp && !rhs.m_opaque_sp) || (rhs.m_opaque_sp && !m_opaque_sp);
87}
88
89break_id_t SBBreakpoint::GetID() const {
90 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
91
92 break_id_t break_id = LLDB_INVALID_BREAK_ID;
93 if (m_opaque_sp)
94 break_id = m_opaque_sp->GetID();
95
96 if (log) {
97 if (break_id == LLDB_INVALID_BREAK_ID)
98 log->Printf("SBBreakpoint(%p)::GetID () => LLDB_INVALID_BREAK_ID",
99 static_cast<void *>(m_opaque_sp.get()));
100 else
101 log->Printf("SBBreakpoint(%p)::GetID () => %u",
102 static_cast<void *>(m_opaque_sp.get()), break_id);
103 }
104
105 return break_id;
106}
107
108bool SBBreakpoint::IsValid() const {
109 if (!m_opaque_sp)
110 return false;
111 else if (m_opaque_sp->GetTarget().GetBreakpointByID(m_opaque_sp->GetID()))
112 return true;
113 else
Greg Claytonac2eb9b2010-12-12 19:25:26 +0000114 return false;
115}
116
Kate Stoneb9c1b512016-09-06 20:57:50 +0000117void SBBreakpoint::ClearAllBreakpointSites() {
118 if (m_opaque_sp) {
119 std::lock_guard<std::recursive_mutex> guard(
120 m_opaque_sp->GetTarget().GetAPIMutex());
121 m_opaque_sp->ClearAllBreakpointSites();
122 }
Enrico Granatac3387332013-05-03 01:29:27 +0000123}
124
Kate Stoneb9c1b512016-09-06 20:57:50 +0000125SBBreakpointLocation SBBreakpoint::FindLocationByAddress(addr_t vm_addr) {
126 SBBreakpointLocation sb_bp_location;
Caroline Ticeceb6b132010-10-26 03:11:13 +0000127
Kate Stoneb9c1b512016-09-06 20:57:50 +0000128 if (m_opaque_sp) {
129 if (vm_addr != LLDB_INVALID_ADDRESS) {
130 std::lock_guard<std::recursive_mutex> guard(
131 m_opaque_sp->GetTarget().GetAPIMutex());
132 Address address;
133 Target &target = m_opaque_sp->GetTarget();
134 if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
135 address.SetRawAddress(vm_addr);
136 }
137 sb_bp_location.SetLocation(m_opaque_sp->FindLocationByAddress(address));
Greg Claytonaf67cec2010-12-20 20:49:23 +0000138 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000139 }
140 return sb_bp_location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000141}
142
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143break_id_t SBBreakpoint::FindLocationIDByAddress(addr_t vm_addr) {
144 break_id_t break_id = LLDB_INVALID_BREAK_ID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000145
Kate Stoneb9c1b512016-09-06 20:57:50 +0000146 if (m_opaque_sp && vm_addr != LLDB_INVALID_ADDRESS) {
147 std::lock_guard<std::recursive_mutex> guard(
148 m_opaque_sp->GetTarget().GetAPIMutex());
149 Address address;
150 Target &target = m_opaque_sp->GetTarget();
151 if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address)) {
152 address.SetRawAddress(vm_addr);
Greg Claytonaf67cec2010-12-20 20:49:23 +0000153 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000154 break_id = m_opaque_sp->FindLocationIDByAddress(address);
155 }
156
157 return break_id;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000158}
159
Kate Stoneb9c1b512016-09-06 20:57:50 +0000160SBBreakpointLocation SBBreakpoint::FindLocationByID(break_id_t bp_loc_id) {
161 SBBreakpointLocation sb_bp_location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000162
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163 if (m_opaque_sp) {
164 std::lock_guard<std::recursive_mutex> guard(
165 m_opaque_sp->GetTarget().GetAPIMutex());
166 sb_bp_location.SetLocation(m_opaque_sp->FindLocationByID(bp_loc_id));
167 }
168
169 return sb_bp_location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000170}
171
Kate Stoneb9c1b512016-09-06 20:57:50 +0000172SBBreakpointLocation SBBreakpoint::GetLocationAtIndex(uint32_t index) {
173 SBBreakpointLocation sb_bp_location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000174
Kate Stoneb9c1b512016-09-06 20:57:50 +0000175 if (m_opaque_sp) {
176 std::lock_guard<std::recursive_mutex> guard(
177 m_opaque_sp->GetTarget().GetAPIMutex());
178 sb_bp_location.SetLocation(m_opaque_sp->GetLocationAtIndex(index));
179 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000180
Kate Stoneb9c1b512016-09-06 20:57:50 +0000181 return sb_bp_location;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000182}
183
Kate Stoneb9c1b512016-09-06 20:57:50 +0000184void SBBreakpoint::SetEnabled(bool enable) {
185 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000186
Kate Stoneb9c1b512016-09-06 20:57:50 +0000187 if (log)
188 log->Printf("SBBreakpoint(%p)::SetEnabled (enabled=%i)",
189 static_cast<void *>(m_opaque_sp.get()), enable);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000190
Kate Stoneb9c1b512016-09-06 20:57:50 +0000191 if (m_opaque_sp) {
192 std::lock_guard<std::recursive_mutex> guard(
193 m_opaque_sp->GetTarget().GetAPIMutex());
194 m_opaque_sp->SetEnabled(enable);
195 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000196}
197
Kate Stoneb9c1b512016-09-06 20:57:50 +0000198bool SBBreakpoint::IsEnabled() {
199 if (m_opaque_sp) {
200 std::lock_guard<std::recursive_mutex> guard(
201 m_opaque_sp->GetTarget().GetAPIMutex());
202 return m_opaque_sp->IsEnabled();
203 } else
Greg Clayton05faeb72010-10-07 04:19:01 +0000204 return false;
Caroline Ticedde9cff2010-09-20 05:20:02 +0000205}
206
Kate Stoneb9c1b512016-09-06 20:57:50 +0000207void SBBreakpoint::SetOneShot(bool one_shot) {
208 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000209
Kate Stoneb9c1b512016-09-06 20:57:50 +0000210 if (log)
211 log->Printf("SBBreakpoint(%p)::SetOneShot (one_shot=%i)",
212 static_cast<void *>(m_opaque_sp.get()), one_shot);
213
214 if (m_opaque_sp) {
215 std::lock_guard<std::recursive_mutex> guard(
216 m_opaque_sp->GetTarget().GetAPIMutex());
217 m_opaque_sp->SetOneShot(one_shot);
218 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000219}
220
Kate Stoneb9c1b512016-09-06 20:57:50 +0000221bool SBBreakpoint::IsOneShot() const {
222 if (m_opaque_sp) {
223 std::lock_guard<std::recursive_mutex> guard(
224 m_opaque_sp->GetTarget().GetAPIMutex());
225 return m_opaque_sp->IsOneShot();
226 } else
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000227 return false;
228}
229
Kate Stoneb9c1b512016-09-06 20:57:50 +0000230bool SBBreakpoint::IsInternal() {
231 if (m_opaque_sp) {
232 std::lock_guard<std::recursive_mutex> guard(
233 m_opaque_sp->GetTarget().GetAPIMutex());
234 return m_opaque_sp->IsInternal();
235 } else
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000236 return false;
237}
238
Kate Stoneb9c1b512016-09-06 20:57:50 +0000239void SBBreakpoint::SetIgnoreCount(uint32_t count) {
240 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000241
Kate Stoneb9c1b512016-09-06 20:57:50 +0000242 if (log)
243 log->Printf("SBBreakpoint(%p)::SetIgnoreCount (count=%u)",
244 static_cast<void *>(m_opaque_sp.get()), count);
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000245
Kate Stoneb9c1b512016-09-06 20:57:50 +0000246 if (m_opaque_sp) {
247 std::lock_guard<std::recursive_mutex> guard(
248 m_opaque_sp->GetTarget().GetAPIMutex());
249 m_opaque_sp->SetIgnoreCount(count);
250 }
251}
252
253void SBBreakpoint::SetCondition(const char *condition) {
254 if (m_opaque_sp) {
255 std::lock_guard<std::recursive_mutex> guard(
256 m_opaque_sp->GetTarget().GetAPIMutex());
257 m_opaque_sp->SetCondition(condition);
258 }
259}
260
261const char *SBBreakpoint::GetCondition() {
262 if (m_opaque_sp) {
263 std::lock_guard<std::recursive_mutex> guard(
264 m_opaque_sp->GetTarget().GetAPIMutex());
265 return m_opaque_sp->GetConditionText();
266 }
267 return nullptr;
268}
269
270uint32_t SBBreakpoint::GetHitCount() const {
271 uint32_t count = 0;
272 if (m_opaque_sp) {
273 std::lock_guard<std::recursive_mutex> guard(
274 m_opaque_sp->GetTarget().GetAPIMutex());
275 count = m_opaque_sp->GetHitCount();
276 }
277
278 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
279 if (log)
280 log->Printf("SBBreakpoint(%p)::GetHitCount () => %u",
281 static_cast<void *>(m_opaque_sp.get()), count);
282
283 return count;
284}
285
286uint32_t SBBreakpoint::GetIgnoreCount() const {
287 uint32_t count = 0;
288 if (m_opaque_sp) {
289 std::lock_guard<std::recursive_mutex> guard(
290 m_opaque_sp->GetTarget().GetAPIMutex());
291 count = m_opaque_sp->GetIgnoreCount();
292 }
293
294 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
295 if (log)
296 log->Printf("SBBreakpoint(%p)::GetIgnoreCount () => %u",
297 static_cast<void *>(m_opaque_sp.get()), count);
298
299 return count;
300}
301
302void SBBreakpoint::SetThreadID(tid_t tid) {
303 if (m_opaque_sp) {
304 std::lock_guard<std::recursive_mutex> guard(
305 m_opaque_sp->GetTarget().GetAPIMutex());
306 m_opaque_sp->SetThreadID(tid);
307 }
308 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
309 if (log)
310 log->Printf("SBBreakpoint(%p)::SetThreadID (tid=0x%4.4" PRIx64 ")",
311 static_cast<void *>(m_opaque_sp.get()), tid);
312}
313
314tid_t SBBreakpoint::GetThreadID() {
315 tid_t tid = LLDB_INVALID_THREAD_ID;
316 if (m_opaque_sp) {
317 std::lock_guard<std::recursive_mutex> guard(
318 m_opaque_sp->GetTarget().GetAPIMutex());
319 tid = m_opaque_sp->GetThreadID();
320 }
321
322 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
323 if (log)
324 log->Printf("SBBreakpoint(%p)::GetThreadID () => 0x%4.4" PRIx64,
325 static_cast<void *>(m_opaque_sp.get()), tid);
326 return tid;
327}
328
329void SBBreakpoint::SetThreadIndex(uint32_t index) {
330 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
331 if (log)
332 log->Printf("SBBreakpoint(%p)::SetThreadIndex (%u)",
333 static_cast<void *>(m_opaque_sp.get()), index);
334 if (m_opaque_sp) {
335 std::lock_guard<std::recursive_mutex> guard(
336 m_opaque_sp->GetTarget().GetAPIMutex());
337 m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex(index);
338 }
339}
340
341uint32_t SBBreakpoint::GetThreadIndex() const {
342 uint32_t thread_idx = UINT32_MAX;
343 if (m_opaque_sp) {
344 std::lock_guard<std::recursive_mutex> guard(
345 m_opaque_sp->GetTarget().GetAPIMutex());
346 const ThreadSpec *thread_spec =
347 m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
348 if (thread_spec != nullptr)
349 thread_idx = thread_spec->GetIndex();
350 }
351 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
352 if (log)
353 log->Printf("SBBreakpoint(%p)::GetThreadIndex () => %u",
354 static_cast<void *>(m_opaque_sp.get()), thread_idx);
355
356 return thread_idx;
357}
358
359void SBBreakpoint::SetThreadName(const char *thread_name) {
360 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
361 if (log)
362 log->Printf("SBBreakpoint(%p)::SetThreadName (%s)",
363 static_cast<void *>(m_opaque_sp.get()), thread_name);
364
365 if (m_opaque_sp) {
366 std::lock_guard<std::recursive_mutex> guard(
367 m_opaque_sp->GetTarget().GetAPIMutex());
368 m_opaque_sp->GetOptions()->GetThreadSpec()->SetName(thread_name);
369 }
370}
371
372const char *SBBreakpoint::GetThreadName() const {
373 const char *name = nullptr;
374 if (m_opaque_sp) {
375 std::lock_guard<std::recursive_mutex> guard(
376 m_opaque_sp->GetTarget().GetAPIMutex());
377 const ThreadSpec *thread_spec =
378 m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
379 if (thread_spec != nullptr)
380 name = thread_spec->GetName();
381 }
382 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
383 if (log)
384 log->Printf("SBBreakpoint(%p)::GetThreadName () => %s",
385 static_cast<void *>(m_opaque_sp.get()), name);
386
387 return name;
388}
389
390void SBBreakpoint::SetQueueName(const char *queue_name) {
391 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
392 if (log)
393 log->Printf("SBBreakpoint(%p)::SetQueueName (%s)",
394 static_cast<void *>(m_opaque_sp.get()), queue_name);
395 if (m_opaque_sp) {
396 std::lock_guard<std::recursive_mutex> guard(
397 m_opaque_sp->GetTarget().GetAPIMutex());
398 m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName(queue_name);
399 }
400}
401
402const char *SBBreakpoint::GetQueueName() const {
403 const char *name = nullptr;
404 if (m_opaque_sp) {
405 std::lock_guard<std::recursive_mutex> guard(
406 m_opaque_sp->GetTarget().GetAPIMutex());
407 const ThreadSpec *thread_spec =
408 m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
409 if (thread_spec)
410 name = thread_spec->GetQueueName();
411 }
412 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
413 if (log)
414 log->Printf("SBBreakpoint(%p)::GetQueueName () => %s",
415 static_cast<void *>(m_opaque_sp.get()), name);
416
417 return name;
418}
419
420size_t SBBreakpoint::GetNumResolvedLocations() const {
421 size_t num_resolved = 0;
422 if (m_opaque_sp) {
423 std::lock_guard<std::recursive_mutex> guard(
424 m_opaque_sp->GetTarget().GetAPIMutex());
425 num_resolved = m_opaque_sp->GetNumResolvedLocations();
426 }
427 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
428 if (log)
429 log->Printf("SBBreakpoint(%p)::GetNumResolvedLocations () => %" PRIu64,
430 static_cast<void *>(m_opaque_sp.get()),
431 static_cast<uint64_t>(num_resolved));
432 return num_resolved;
433}
434
435size_t SBBreakpoint::GetNumLocations() const {
436 size_t num_locs = 0;
437 if (m_opaque_sp) {
438 std::lock_guard<std::recursive_mutex> guard(
439 m_opaque_sp->GetTarget().GetAPIMutex());
440 num_locs = m_opaque_sp->GetNumLocations();
441 }
442 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
443 if (log)
444 log->Printf("SBBreakpoint(%p)::GetNumLocations () => %" PRIu64,
445 static_cast<void *>(m_opaque_sp.get()),
446 static_cast<uint64_t>(num_locs));
447 return num_locs;
448}
449
450bool SBBreakpoint::GetDescription(SBStream &s) {
451 if (m_opaque_sp) {
452 std::lock_guard<std::recursive_mutex> guard(
453 m_opaque_sp->GetTarget().GetAPIMutex());
454 s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID());
455 m_opaque_sp->GetResolverDescription(s.get());
456 m_opaque_sp->GetFilterDescription(s.get());
457 const size_t num_locations = m_opaque_sp->GetNumLocations();
458 s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
459 return true;
460 }
461 s.Printf("No value");
462 return false;
463}
464
465bool SBBreakpoint::PrivateBreakpointHitCallback(void *baton,
466 StoppointCallbackContext *ctx,
467 lldb::user_id_t break_id,
468 lldb::user_id_t break_loc_id) {
469 ExecutionContext exe_ctx(ctx->exe_ctx_ref);
470 BreakpointSP bp_sp(
471 exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
472 if (baton && bp_sp) {
473 CallbackData *data = (CallbackData *)baton;
474 lldb_private::Breakpoint *bp = bp_sp.get();
475 if (bp && data->callback) {
476 Process *process = exe_ctx.GetProcessPtr();
477 if (process) {
478 SBProcess sb_process(process->shared_from_this());
479 SBThread sb_thread;
480 SBBreakpointLocation sb_location;
481 assert(bp_sp);
482 sb_location.SetLocation(bp_sp->FindLocationByID(break_loc_id));
483 Thread *thread = exe_ctx.GetThreadPtr();
484 if (thread)
485 sb_thread.SetThread(thread->shared_from_this());
486
487 return data->callback(data->callback_baton, sb_process, sb_thread,
488 sb_location);
489 }
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000490 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000491 }
492 return true; // Return true if we should stop at this breakpoint
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000493}
494
Kate Stoneb9c1b512016-09-06 20:57:50 +0000495void SBBreakpoint::SetCallback(BreakpointHitCallback callback, void *baton) {
496 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
497
498 if (log) {
499 void *pointer = &callback;
500 log->Printf("SBBreakpoint(%p)::SetCallback (callback=%p, baton=%p)",
501 static_cast<void *>(m_opaque_sp.get()),
502 *static_cast<void **>(&pointer), static_cast<void *>(baton));
503 }
504
505 if (m_opaque_sp) {
506 std::lock_guard<std::recursive_mutex> guard(
507 m_opaque_sp->GetTarget().GetAPIMutex());
508 BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
509 m_opaque_sp->SetCallback(SBBreakpoint::PrivateBreakpointHitCallback,
510 baton_sp, false);
511 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000512}
513
Kate Stoneb9c1b512016-09-06 20:57:50 +0000514void SBBreakpoint::SetScriptCallbackFunction(
515 const char *callback_function_name) {
516 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
517
518 if (log)
519 log->Printf("SBBreakpoint(%p)::SetScriptCallbackFunction (callback=%s)",
520 static_cast<void *>(m_opaque_sp.get()), callback_function_name);
521
522 if (m_opaque_sp) {
523 std::lock_guard<std::recursive_mutex> guard(
524 m_opaque_sp->GetTarget().GetAPIMutex());
525 BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
526 m_opaque_sp->GetTarget()
527 .GetDebugger()
528 .GetCommandInterpreter()
529 .GetScriptInterpreter()
530 ->SetBreakpointCommandCallbackFunction(bp_options,
531 callback_function_name);
532 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000533}
534
Kate Stoneb9c1b512016-09-06 20:57:50 +0000535SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) {
536 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
537
538 if (log)
539 log->Printf("SBBreakpoint(%p)::SetScriptCallbackBody: callback body:\n%s)",
540 static_cast<void *>(m_opaque_sp.get()), callback_body_text);
541
542 SBError sb_error;
543 if (m_opaque_sp) {
544 std::lock_guard<std::recursive_mutex> guard(
545 m_opaque_sp->GetTarget().GetAPIMutex());
546 BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
547 Error error =
548 m_opaque_sp->GetTarget()
549 .GetDebugger()
550 .GetCommandInterpreter()
551 .GetScriptInterpreter()
552 ->SetBreakpointCommandCallback(bp_options, callback_body_text);
553 sb_error.SetError(error);
554 } else
555 sb_error.SetErrorString("invalid breakpoint");
556
557 return sb_error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000558}
559
Kate Stoneb9c1b512016-09-06 20:57:50 +0000560bool SBBreakpoint::AddName(const char *new_name) {
561 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
562
563 if (log)
564 log->Printf("SBBreakpoint(%p)::AddName (name=%s)",
565 static_cast<void *>(m_opaque_sp.get()), new_name);
566
567 if (m_opaque_sp) {
568 std::lock_guard<std::recursive_mutex> guard(
569 m_opaque_sp->GetTarget().GetAPIMutex());
570 Error error; // Think I'm just going to swallow the error here, it's
571 // probably more annoying to have to provide it.
572 return m_opaque_sp->AddName(new_name, error);
573 }
574
575 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000576}
577
Kate Stoneb9c1b512016-09-06 20:57:50 +0000578void SBBreakpoint::RemoveName(const char *name_to_remove) {
579 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
580
581 if (log)
582 log->Printf("SBBreakpoint(%p)::RemoveName (name=%s)",
583 static_cast<void *>(m_opaque_sp.get()), name_to_remove);
584
585 if (m_opaque_sp) {
586 std::lock_guard<std::recursive_mutex> guard(
587 m_opaque_sp->GetTarget().GetAPIMutex());
588 m_opaque_sp->RemoveName(name_to_remove);
589 }
590}
591
592bool SBBreakpoint::MatchesName(const char *name) {
593 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
594
595 if (log)
596 log->Printf("SBBreakpoint(%p)::MatchesName (name=%s)",
597 static_cast<void *>(m_opaque_sp.get()), name);
598
599 if (m_opaque_sp) {
600 std::lock_guard<std::recursive_mutex> guard(
601 m_opaque_sp->GetTarget().GetAPIMutex());
602 return m_opaque_sp->MatchesName(name);
603 }
604
605 return false;
606}
607
608void SBBreakpoint::GetNames(SBStringList &names) {
609 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
610
611 if (log)
612 log->Printf("SBBreakpoint(%p)::GetNames ()",
613 static_cast<void *>(m_opaque_sp.get()));
614
615 if (m_opaque_sp) {
616 std::lock_guard<std::recursive_mutex> guard(
617 m_opaque_sp->GetTarget().GetAPIMutex());
618 std::vector<std::string> names_vec;
619 m_opaque_sp->GetNames(names_vec);
620 for (std::string name : names_vec) {
621 names.AppendString(name.c_str());
622 }
623 }
624}
625
626lldb_private::Breakpoint *SBBreakpoint::operator->() const {
627 return m_opaque_sp.get();
628}
629
630lldb_private::Breakpoint *SBBreakpoint::get() const {
631 return m_opaque_sp.get();
632}
633
634lldb::BreakpointSP &SBBreakpoint::operator*() { return m_opaque_sp; }
635
636const lldb::BreakpointSP &SBBreakpoint::operator*() const {
637 return m_opaque_sp;
638}
639
640bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) {
641 return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) !=
642 nullptr;
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000643}
644
Greg Clayton9fed0d82010-07-23 23:33:17 +0000645BreakpointEventType
Kate Stoneb9c1b512016-09-06 20:57:50 +0000646SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) {
647 if (event.IsValid())
648 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
649 event.GetSP());
650 return eBreakpointEventTypeInvalidType;
Greg Clayton9fed0d82010-07-23 23:33:17 +0000651}
652
Kate Stoneb9c1b512016-09-06 20:57:50 +0000653SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) {
654 SBBreakpoint sb_breakpoint;
655 if (event.IsValid())
656 sb_breakpoint.m_opaque_sp =
657 Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event.GetSP());
658 return sb_breakpoint;
Greg Clayton9fed0d82010-07-23 23:33:17 +0000659}
660
661SBBreakpointLocation
Kate Stoneb9c1b512016-09-06 20:57:50 +0000662SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event,
663 uint32_t loc_idx) {
664 SBBreakpointLocation sb_breakpoint_loc;
665 if (event.IsValid())
666 sb_breakpoint_loc.SetLocation(
667 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent(
668 event.GetSP(), loc_idx));
669 return sb_breakpoint_loc;
Greg Clayton9fed0d82010-07-23 23:33:17 +0000670}
671
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000672uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000673SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) {
674 uint32_t num_locations = 0;
675 if (event.IsValid())
676 num_locations =
677 (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
678 event.GetSP()));
679 return num_locations;
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000680}