blob: 0eab2c2a363facfc2a4c144de9caf4878ecc4e5a [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
Jim Ingham92d19602016-09-20 22:54:49 +0000451void SBBreakpoint::SetCommandLineCommands(SBStringList &commands) {
452 if (!m_opaque_sp)
453 return;
454 if (commands.GetSize() == 0)
455 return;
456
457 std::lock_guard<std::recursive_mutex> guard(
458 m_opaque_sp->GetTarget().GetAPIMutex());
459 std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(
Jim Inghamf7e07252016-09-26 19:47:37 +0000460 new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));
Jim Ingham92d19602016-09-20 22:54:49 +0000461
462 m_opaque_sp->GetOptions()->SetCommandDataCallback(cmd_data_up);
463}
464
465bool SBBreakpoint::GetCommandLineCommands(SBStringList &commands) {
466 if (!m_opaque_sp)
467 return false;
468 StringList command_list;
469 bool has_commands =
470 m_opaque_sp->GetOptions()->GetCommandLineCallbacks(command_list);
471 if (has_commands)
472 commands.AppendList(command_list);
473 return has_commands;
474}
475
Kate Stoneb9c1b512016-09-06 20:57:50 +0000476bool SBBreakpoint::GetDescription(SBStream &s) {
Jim Ingham6d1e4692016-09-16 01:41:27 +0000477 return GetDescription(s, true);
478}
479
480bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000481 if (m_opaque_sp) {
482 std::lock_guard<std::recursive_mutex> guard(
483 m_opaque_sp->GetTarget().GetAPIMutex());
484 s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID());
485 m_opaque_sp->GetResolverDescription(s.get());
486 m_opaque_sp->GetFilterDescription(s.get());
Jim Ingham6d1e4692016-09-16 01:41:27 +0000487 if (include_locations) {
488 const size_t num_locations = m_opaque_sp->GetNumLocations();
489 s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
490 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000491 return true;
492 }
493 s.Printf("No value");
494 return false;
495}
496
497bool SBBreakpoint::PrivateBreakpointHitCallback(void *baton,
498 StoppointCallbackContext *ctx,
499 lldb::user_id_t break_id,
500 lldb::user_id_t break_loc_id) {
501 ExecutionContext exe_ctx(ctx->exe_ctx_ref);
502 BreakpointSP bp_sp(
503 exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
504 if (baton && bp_sp) {
505 CallbackData *data = (CallbackData *)baton;
506 lldb_private::Breakpoint *bp = bp_sp.get();
507 if (bp && data->callback) {
508 Process *process = exe_ctx.GetProcessPtr();
509 if (process) {
510 SBProcess sb_process(process->shared_from_this());
511 SBThread sb_thread;
512 SBBreakpointLocation sb_location;
513 assert(bp_sp);
514 sb_location.SetLocation(bp_sp->FindLocationByID(break_loc_id));
515 Thread *thread = exe_ctx.GetThreadPtr();
516 if (thread)
517 sb_thread.SetThread(thread->shared_from_this());
518
519 return data->callback(data->callback_baton, sb_process, sb_thread,
520 sb_location);
521 }
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000522 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000523 }
524 return true; // Return true if we should stop at this breakpoint
Jim Ingham5e09c8c2014-12-16 23:40:14 +0000525}
526
Kate Stoneb9c1b512016-09-06 20:57:50 +0000527void SBBreakpoint::SetCallback(BreakpointHitCallback callback, void *baton) {
528 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
529
530 if (log) {
531 void *pointer = &callback;
532 log->Printf("SBBreakpoint(%p)::SetCallback (callback=%p, baton=%p)",
533 static_cast<void *>(m_opaque_sp.get()),
534 *static_cast<void **>(&pointer), static_cast<void *>(baton));
535 }
536
537 if (m_opaque_sp) {
538 std::lock_guard<std::recursive_mutex> guard(
539 m_opaque_sp->GetTarget().GetAPIMutex());
540 BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
541 m_opaque_sp->SetCallback(SBBreakpoint::PrivateBreakpointHitCallback,
542 baton_sp, false);
543 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000544}
545
Kate Stoneb9c1b512016-09-06 20:57:50 +0000546void SBBreakpoint::SetScriptCallbackFunction(
547 const char *callback_function_name) {
548 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
549
550 if (log)
551 log->Printf("SBBreakpoint(%p)::SetScriptCallbackFunction (callback=%s)",
552 static_cast<void *>(m_opaque_sp.get()), callback_function_name);
553
554 if (m_opaque_sp) {
555 std::lock_guard<std::recursive_mutex> guard(
556 m_opaque_sp->GetTarget().GetAPIMutex());
557 BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
558 m_opaque_sp->GetTarget()
559 .GetDebugger()
560 .GetCommandInterpreter()
561 .GetScriptInterpreter()
562 ->SetBreakpointCommandCallbackFunction(bp_options,
563 callback_function_name);
564 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000565}
566
Kate Stoneb9c1b512016-09-06 20:57:50 +0000567SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) {
568 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
569
570 if (log)
571 log->Printf("SBBreakpoint(%p)::SetScriptCallbackBody: callback body:\n%s)",
572 static_cast<void *>(m_opaque_sp.get()), callback_body_text);
573
574 SBError sb_error;
575 if (m_opaque_sp) {
576 std::lock_guard<std::recursive_mutex> guard(
577 m_opaque_sp->GetTarget().GetAPIMutex());
578 BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
579 Error error =
580 m_opaque_sp->GetTarget()
581 .GetDebugger()
582 .GetCommandInterpreter()
583 .GetScriptInterpreter()
584 ->SetBreakpointCommandCallback(bp_options, callback_body_text);
585 sb_error.SetError(error);
586 } else
587 sb_error.SetErrorString("invalid breakpoint");
588
589 return sb_error;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000590}
591
Kate Stoneb9c1b512016-09-06 20:57:50 +0000592bool SBBreakpoint::AddName(const char *new_name) {
593 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
594
595 if (log)
596 log->Printf("SBBreakpoint(%p)::AddName (name=%s)",
597 static_cast<void *>(m_opaque_sp.get()), new_name);
598
599 if (m_opaque_sp) {
600 std::lock_guard<std::recursive_mutex> guard(
601 m_opaque_sp->GetTarget().GetAPIMutex());
602 Error error; // Think I'm just going to swallow the error here, it's
603 // probably more annoying to have to provide it.
604 return m_opaque_sp->AddName(new_name, error);
605 }
606
607 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000608}
609
Kate Stoneb9c1b512016-09-06 20:57:50 +0000610void SBBreakpoint::RemoveName(const char *name_to_remove) {
611 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
612
613 if (log)
614 log->Printf("SBBreakpoint(%p)::RemoveName (name=%s)",
615 static_cast<void *>(m_opaque_sp.get()), name_to_remove);
616
617 if (m_opaque_sp) {
618 std::lock_guard<std::recursive_mutex> guard(
619 m_opaque_sp->GetTarget().GetAPIMutex());
620 m_opaque_sp->RemoveName(name_to_remove);
621 }
622}
623
624bool SBBreakpoint::MatchesName(const char *name) {
625 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
626
627 if (log)
628 log->Printf("SBBreakpoint(%p)::MatchesName (name=%s)",
629 static_cast<void *>(m_opaque_sp.get()), name);
630
631 if (m_opaque_sp) {
632 std::lock_guard<std::recursive_mutex> guard(
633 m_opaque_sp->GetTarget().GetAPIMutex());
634 return m_opaque_sp->MatchesName(name);
635 }
636
637 return false;
638}
639
640void SBBreakpoint::GetNames(SBStringList &names) {
641 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
642
643 if (log)
644 log->Printf("SBBreakpoint(%p)::GetNames ()",
645 static_cast<void *>(m_opaque_sp.get()));
646
647 if (m_opaque_sp) {
648 std::lock_guard<std::recursive_mutex> guard(
649 m_opaque_sp->GetTarget().GetAPIMutex());
650 std::vector<std::string> names_vec;
651 m_opaque_sp->GetNames(names_vec);
652 for (std::string name : names_vec) {
653 names.AppendString(name.c_str());
654 }
655 }
656}
657
658lldb_private::Breakpoint *SBBreakpoint::operator->() const {
659 return m_opaque_sp.get();
660}
661
662lldb_private::Breakpoint *SBBreakpoint::get() const {
663 return m_opaque_sp.get();
664}
665
666lldb::BreakpointSP &SBBreakpoint::operator*() { return m_opaque_sp; }
667
668const lldb::BreakpointSP &SBBreakpoint::operator*() const {
669 return m_opaque_sp;
670}
671
672bool SBBreakpoint::EventIsBreakpointEvent(const lldb::SBEvent &event) {
673 return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) !=
674 nullptr;
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000675}
676
Greg Clayton9fed0d82010-07-23 23:33:17 +0000677BreakpointEventType
Kate Stoneb9c1b512016-09-06 20:57:50 +0000678SBBreakpoint::GetBreakpointEventTypeFromEvent(const SBEvent &event) {
679 if (event.IsValid())
680 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
681 event.GetSP());
682 return eBreakpointEventTypeInvalidType;
Greg Clayton9fed0d82010-07-23 23:33:17 +0000683}
684
Kate Stoneb9c1b512016-09-06 20:57:50 +0000685SBBreakpoint SBBreakpoint::GetBreakpointFromEvent(const lldb::SBEvent &event) {
686 SBBreakpoint sb_breakpoint;
687 if (event.IsValid())
688 sb_breakpoint.m_opaque_sp =
689 Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event.GetSP());
690 return sb_breakpoint;
Greg Clayton9fed0d82010-07-23 23:33:17 +0000691}
692
693SBBreakpointLocation
Kate Stoneb9c1b512016-09-06 20:57:50 +0000694SBBreakpoint::GetBreakpointLocationAtIndexFromEvent(const lldb::SBEvent &event,
695 uint32_t loc_idx) {
696 SBBreakpointLocation sb_breakpoint_loc;
697 if (event.IsValid())
698 sb_breakpoint_loc.SetLocation(
699 Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent(
700 event.GetSP(), loc_idx));
701 return sb_breakpoint_loc;
Greg Clayton9fed0d82010-07-23 23:33:17 +0000702}
703
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000704uint32_t
Kate Stoneb9c1b512016-09-06 20:57:50 +0000705SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) {
706 uint32_t num_locations = 0;
707 if (event.IsValid())
708 num_locations =
709 (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
710 event.GetSP()));
711 return num_locations;
Jim Inghame6bc6cb2012-02-08 05:23:15 +0000712}
Jim Ingham01f16662016-09-14 19:07:35 +0000713
714// This is simple collection of breakpoint id's and their target.
Todd Fiala653e3f42016-11-11 21:06:40 +0000715class SBBreakpointListImpl {
Jim Ingham01f16662016-09-14 19:07:35 +0000716public:
Todd Fiala653e3f42016-11-11 21:06:40 +0000717 SBBreakpointListImpl(lldb::TargetSP target_sp) : m_target_wp() {
718 if (target_sp && target_sp->IsValid())
719 m_target_wp = target_sp;
Jim Ingham01f16662016-09-14 19:07:35 +0000720 }
721
722 ~SBBreakpointListImpl() = default;
723
724 size_t GetSize() { return m_break_ids.size(); }
725
726 BreakpointSP GetBreakpointAtIndex(size_t idx) {
727 if (idx >= m_break_ids.size())
728 return BreakpointSP();
729 TargetSP target_sp = m_target_wp.lock();
730 if (!target_sp)
731 return BreakpointSP();
732 lldb::break_id_t bp_id = m_break_ids[idx];
733 return target_sp->GetBreakpointList().FindBreakpointByID(bp_id);
734 }
735
Jim Ingham6d1e4692016-09-16 01:41:27 +0000736 BreakpointSP FindBreakpointByID(lldb::break_id_t desired_id) {
737 TargetSP target_sp = m_target_wp.lock();
738 if (!target_sp)
739 return BreakpointSP();
740
741 for (lldb::break_id_t &break_id : m_break_ids) {
742 if (break_id == desired_id)
743 return target_sp->GetBreakpointList().FindBreakpointByID(break_id);
744 }
745 return BreakpointSP();
746 }
747
Jim Ingham01f16662016-09-14 19:07:35 +0000748 bool Append(Breakpoint &bkpt) {
749 TargetSP target_sp = m_target_wp.lock();
750 if (!target_sp)
751 return false;
752 if (bkpt.GetTargetSP() != target_sp)
753 return false;
754 m_break_ids.push_back(bkpt.GetID());
755 return true;
756 }
757
758 bool AppendIfUnique(Breakpoint &bkpt) {
759 TargetSP target_sp = m_target_wp.lock();
760 if (!target_sp)
761 return false;
762 if (bkpt.GetTargetSP() != target_sp)
763 return false;
764 lldb::break_id_t bp_id = bkpt.GetID();
765 if (find(m_break_ids.begin(), m_break_ids.end(), bp_id) ==
766 m_break_ids.end())
767 return false;
768
769 m_break_ids.push_back(bkpt.GetID());
770 return true;
771 }
772
773 bool AppendByID(lldb::break_id_t id) {
774 TargetSP target_sp = m_target_wp.lock();
775 if (!target_sp)
776 return false;
777 if (id == LLDB_INVALID_BREAK_ID)
778 return false;
779 m_break_ids.push_back(id);
780 return true;
781 }
782
783 void Clear() { m_break_ids.clear(); }
784
785 void CopyToBreakpointIDList(lldb_private::BreakpointIDList &bp_list) {
786 for (lldb::break_id_t id : m_break_ids) {
787 bp_list.AddBreakpointID(BreakpointID(id));
788 }
789 }
790
791 TargetSP GetTarget() { return m_target_wp.lock(); }
792
793private:
794 std::vector<lldb::break_id_t> m_break_ids;
795 TargetWP m_target_wp;
796};
797
798SBBreakpointList::SBBreakpointList(SBTarget &target)
Todd Fiala653e3f42016-11-11 21:06:40 +0000799 : m_opaque_sp(new SBBreakpointListImpl(target.GetSP())) {}
Jim Ingham01f16662016-09-14 19:07:35 +0000800
801SBBreakpointList::~SBBreakpointList() {}
802
803size_t SBBreakpointList::GetSize() const {
804 if (!m_opaque_sp)
805 return 0;
806 else
807 return m_opaque_sp->GetSize();
808}
809
810SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) {
811 if (!m_opaque_sp)
812 return SBBreakpoint();
813
814 BreakpointSP bkpt_sp = m_opaque_sp->GetBreakpointAtIndex(idx);
815 return SBBreakpoint(bkpt_sp);
816}
817
Jim Ingham6d1e4692016-09-16 01:41:27 +0000818SBBreakpoint SBBreakpointList::FindBreakpointByID(lldb::break_id_t id) {
819 if (!m_opaque_sp)
820 return SBBreakpoint();
821 BreakpointSP bkpt_sp = m_opaque_sp->FindBreakpointByID(id);
822 return SBBreakpoint(bkpt_sp);
823}
824
Jim Ingham01f16662016-09-14 19:07:35 +0000825void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) {
826 if (!sb_bkpt.IsValid())
827 return;
828 if (!m_opaque_sp)
829 return;
830 m_opaque_sp->Append(*sb_bkpt.get());
831}
832
833void SBBreakpointList::AppendByID(lldb::break_id_t id) {
834 if (!m_opaque_sp)
835 return;
836 m_opaque_sp->AppendByID(id);
837}
838
839bool SBBreakpointList::AppendIfUnique(const SBBreakpoint &sb_bkpt) {
840 if (!sb_bkpt.IsValid())
841 return false;
842 if (!m_opaque_sp)
843 return false;
844 return m_opaque_sp->AppendIfUnique(*sb_bkpt.get());
845}
846
847void SBBreakpointList::Clear() {
848 if (m_opaque_sp)
849 m_opaque_sp->Clear();
850}
851
852void SBBreakpointList::CopyToBreakpointIDList(
853 lldb_private::BreakpointIDList &bp_id_list) {
854 if (m_opaque_sp)
855 m_opaque_sp->CopyToBreakpointIDList(bp_id_list);
856}