1 //===-- SBBreakpoint.cpp ----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 // Other libraries and framework includes
14 #include "lldb/API/SBBreakpoint.h"
15 #include "lldb/API/SBBreakpointLocation.h"
16 #include "lldb/API/SBDebugger.h"
17 #include "lldb/API/SBEvent.h"
18 #include "lldb/API/SBProcess.h"
19 #include "lldb/API/SBStream.h"
20 #include "lldb/API/SBStringList.h"
21 #include "lldb/API/SBThread.h"
23 #include "lldb/Breakpoint/Breakpoint.h"
24 #include "lldb/Breakpoint/BreakpointLocation.h"
25 #include "lldb/Breakpoint/StoppointCallbackContext.h"
26 #include "lldb/Core/Address.h"
27 #include "lldb/Core/Debugger.h"
28 #include "lldb/Core/Log.h"
29 #include "lldb/Core/Stream.h"
30 #include "lldb/Core/StreamFile.h"
31 #include "lldb/Interpreter/CommandInterpreter.h"
32 #include "lldb/Interpreter/ScriptInterpreter.h"
33 #include "lldb/Target/Process.h"
34 #include "lldb/Target/SectionLoadList.h"
35 #include "lldb/Target/Target.h"
36 #include "lldb/Target/Thread.h"
37 #include "lldb/Target/ThreadSpec.h"
39 #include "lldb/lldb-enumerations.h"
42 using namespace lldb_private;
46 SBBreakpoint::BreakpointHitCallback callback;
50 class SBBreakpointCallbackBaton : public Baton
53 SBBreakpointCallbackBaton (SBBreakpoint::BreakpointHitCallback callback, void *baton) :
54 Baton (new CallbackData)
56 CallbackData *data = (CallbackData *)m_data;
57 data->callback = callback;
58 data->callback_baton = baton;
61 ~SBBreakpointCallbackBaton() override
63 CallbackData *data = (CallbackData *)m_data;
73 SBBreakpoint::SBBreakpoint () :
78 SBBreakpoint::SBBreakpoint (const SBBreakpoint& rhs) :
79 m_opaque_sp (rhs.m_opaque_sp)
83 SBBreakpoint::SBBreakpoint (const lldb::BreakpointSP &bp_sp) :
88 SBBreakpoint::~SBBreakpoint() = default;
91 SBBreakpoint::operator = (const SBBreakpoint& rhs)
94 m_opaque_sp = rhs.m_opaque_sp;
99 SBBreakpoint::operator == (const lldb::SBBreakpoint& rhs)
101 if (m_opaque_sp && rhs.m_opaque_sp)
102 return m_opaque_sp.get() == rhs.m_opaque_sp.get();
107 SBBreakpoint::operator != (const lldb::SBBreakpoint& rhs)
109 if (m_opaque_sp && rhs.m_opaque_sp)
110 return m_opaque_sp.get() != rhs.m_opaque_sp.get();
111 return (m_opaque_sp && !rhs.m_opaque_sp) || (rhs.m_opaque_sp && !m_opaque_sp);
115 SBBreakpoint::GetID () const
117 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
119 break_id_t break_id = LLDB_INVALID_BREAK_ID;
121 break_id = m_opaque_sp->GetID();
125 if (break_id == LLDB_INVALID_BREAK_ID)
126 log->Printf ("SBBreakpoint(%p)::GetID () => LLDB_INVALID_BREAK_ID",
127 static_cast<void*>(m_opaque_sp.get()));
129 log->Printf ("SBBreakpoint(%p)::GetID () => %u",
130 static_cast<void*>(m_opaque_sp.get()), break_id);
137 SBBreakpoint::IsValid() const
141 else if (m_opaque_sp->GetTarget().GetBreakpointByID(m_opaque_sp->GetID()))
148 SBBreakpoint::ClearAllBreakpointSites ()
152 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
153 m_opaque_sp->ClearAllBreakpointSites ();
158 SBBreakpoint::FindLocationByAddress (addr_t vm_addr)
160 SBBreakpointLocation sb_bp_location;
164 if (vm_addr != LLDB_INVALID_ADDRESS)
166 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
168 Target &target = m_opaque_sp->GetTarget();
169 if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address))
171 address.SetRawAddress (vm_addr);
173 sb_bp_location.SetLocation (m_opaque_sp->FindLocationByAddress (address));
176 return sb_bp_location;
180 SBBreakpoint::FindLocationIDByAddress (addr_t vm_addr)
182 break_id_t break_id = LLDB_INVALID_BREAK_ID;
184 if (m_opaque_sp && vm_addr != LLDB_INVALID_ADDRESS)
186 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
188 Target &target = m_opaque_sp->GetTarget();
189 if (!target.GetSectionLoadList().ResolveLoadAddress(vm_addr, address))
191 address.SetRawAddress (vm_addr);
193 break_id = m_opaque_sp->FindLocationIDByAddress (address);
200 SBBreakpoint::FindLocationByID (break_id_t bp_loc_id)
202 SBBreakpointLocation sb_bp_location;
206 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
207 sb_bp_location.SetLocation (m_opaque_sp->FindLocationByID (bp_loc_id));
210 return sb_bp_location;
214 SBBreakpoint::GetLocationAtIndex (uint32_t index)
216 SBBreakpointLocation sb_bp_location;
220 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
221 sb_bp_location.SetLocation (m_opaque_sp->GetLocationAtIndex (index));
224 return sb_bp_location;
228 SBBreakpoint::SetEnabled (bool enable)
230 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
233 log->Printf ("SBBreakpoint(%p)::SetEnabled (enabled=%i)",
234 static_cast<void*>(m_opaque_sp.get()), enable);
238 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
239 m_opaque_sp->SetEnabled (enable);
244 SBBreakpoint::IsEnabled ()
248 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
249 return m_opaque_sp->IsEnabled();
256 SBBreakpoint::SetOneShot (bool one_shot)
258 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
261 log->Printf ("SBBreakpoint(%p)::SetOneShot (one_shot=%i)",
262 static_cast<void*>(m_opaque_sp.get()), one_shot);
266 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
267 m_opaque_sp->SetOneShot (one_shot);
272 SBBreakpoint::IsOneShot () const
276 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
277 return m_opaque_sp->IsOneShot();
284 SBBreakpoint::IsInternal ()
288 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
289 return m_opaque_sp->IsInternal();
296 SBBreakpoint::SetIgnoreCount (uint32_t count)
298 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
301 log->Printf ("SBBreakpoint(%p)::SetIgnoreCount (count=%u)",
302 static_cast<void*>(m_opaque_sp.get()), count);
306 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
307 m_opaque_sp->SetIgnoreCount (count);
312 SBBreakpoint::SetCondition (const char *condition)
316 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
317 m_opaque_sp->SetCondition (condition);
322 SBBreakpoint::GetCondition ()
326 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
327 return m_opaque_sp->GetConditionText ();
333 SBBreakpoint::GetHitCount () const
338 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
339 count = m_opaque_sp->GetHitCount();
342 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
344 log->Printf ("SBBreakpoint(%p)::GetHitCount () => %u",
345 static_cast<void*>(m_opaque_sp.get()), count);
351 SBBreakpoint::GetIgnoreCount () const
356 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
357 count = m_opaque_sp->GetIgnoreCount();
360 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
362 log->Printf ("SBBreakpoint(%p)::GetIgnoreCount () => %u",
363 static_cast<void*>(m_opaque_sp.get()), count);
369 SBBreakpoint::SetThreadID (tid_t tid)
373 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
374 m_opaque_sp->SetThreadID (tid);
376 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
378 log->Printf ("SBBreakpoint(%p)::SetThreadID (tid=0x%4.4" PRIx64 ")",
379 static_cast<void*>(m_opaque_sp.get()), tid);
383 SBBreakpoint::GetThreadID ()
385 tid_t tid = LLDB_INVALID_THREAD_ID;
388 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
389 tid = m_opaque_sp->GetThreadID();
392 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
394 log->Printf ("SBBreakpoint(%p)::GetThreadID () => 0x%4.4" PRIx64,
395 static_cast<void*>(m_opaque_sp.get()), tid);
400 SBBreakpoint::SetThreadIndex (uint32_t index)
402 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
404 log->Printf ("SBBreakpoint(%p)::SetThreadIndex (%u)",
405 static_cast<void*>(m_opaque_sp.get()), index);
408 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
409 m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex (index);
414 SBBreakpoint::GetThreadIndex() const
416 uint32_t thread_idx = UINT32_MAX;
419 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
420 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
421 if (thread_spec != nullptr)
422 thread_idx = thread_spec->GetIndex();
424 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
426 log->Printf ("SBBreakpoint(%p)::GetThreadIndex () => %u",
427 static_cast<void*>(m_opaque_sp.get()), thread_idx);
433 SBBreakpoint::SetThreadName (const char *thread_name)
435 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
437 log->Printf ("SBBreakpoint(%p)::SetThreadName (%s)",
438 static_cast<void*>(m_opaque_sp.get()), thread_name);
442 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
443 m_opaque_sp->GetOptions()->GetThreadSpec()->SetName (thread_name);
448 SBBreakpoint::GetThreadName () const
450 const char *name = nullptr;
453 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
454 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
455 if (thread_spec != nullptr)
456 name = thread_spec->GetName();
458 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
460 log->Printf ("SBBreakpoint(%p)::GetThreadName () => %s",
461 static_cast<void*>(m_opaque_sp.get()), name);
467 SBBreakpoint::SetQueueName (const char *queue_name)
469 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
471 log->Printf ("SBBreakpoint(%p)::SetQueueName (%s)",
472 static_cast<void*>(m_opaque_sp.get()), queue_name);
475 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
476 m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName (queue_name);
481 SBBreakpoint::GetQueueName () const
483 const char *name = nullptr;
486 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
487 const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate();
489 name = thread_spec->GetQueueName();
491 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
493 log->Printf ("SBBreakpoint(%p)::GetQueueName () => %s",
494 static_cast<void*>(m_opaque_sp.get()), name);
500 SBBreakpoint::GetNumResolvedLocations() const
502 size_t num_resolved = 0;
505 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
506 num_resolved = m_opaque_sp->GetNumResolvedLocations();
508 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
510 log->Printf ("SBBreakpoint(%p)::GetNumResolvedLocations () => %" PRIu64,
511 static_cast<void*>(m_opaque_sp.get()),
512 static_cast<uint64_t>(num_resolved));
517 SBBreakpoint::GetNumLocations() const
522 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
523 num_locs = m_opaque_sp->GetNumLocations();
525 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
527 log->Printf ("SBBreakpoint(%p)::GetNumLocations () => %" PRIu64,
528 static_cast<void*>(m_opaque_sp.get()),
529 static_cast<uint64_t>(num_locs));
534 SBBreakpoint::GetDescription (SBStream &s)
538 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
539 s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID());
540 m_opaque_sp->GetResolverDescription (s.get());
541 m_opaque_sp->GetFilterDescription (s.get());
542 const size_t num_locations = m_opaque_sp->GetNumLocations ();
543 s.Printf(", locations = %" PRIu64, (uint64_t)num_locations);
546 s.Printf ("No value");
551 SBBreakpoint::PrivateBreakpointHitCallback(void *baton,
552 StoppointCallbackContext *ctx,
553 lldb::user_id_t break_id,
554 lldb::user_id_t break_loc_id)
556 ExecutionContext exe_ctx (ctx->exe_ctx_ref);
557 BreakpointSP bp_sp(exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
560 CallbackData *data = (CallbackData *)baton;
561 lldb_private::Breakpoint *bp = bp_sp.get();
562 if (bp && data->callback)
564 Process *process = exe_ctx.GetProcessPtr();
567 SBProcess sb_process (process->shared_from_this());
569 SBBreakpointLocation sb_location;
571 sb_location.SetLocation (bp_sp->FindLocationByID (break_loc_id));
572 Thread *thread = exe_ctx.GetThreadPtr();
574 sb_thread.SetThread(thread->shared_from_this());
576 return data->callback (data->callback_baton,
583 return true; // Return true if we should stop at this breakpoint
587 SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton)
589 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
593 void *pointer = &callback;
594 log->Printf ("SBBreakpoint(%p)::SetCallback (callback=%p, baton=%p)",
595 static_cast<void*>(m_opaque_sp.get()),
596 *static_cast<void**>(&pointer), static_cast<void*>(baton));
601 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
602 BatonSP baton_sp(new SBBreakpointCallbackBaton (callback, baton));
603 m_opaque_sp->SetCallback (SBBreakpoint::PrivateBreakpointHitCallback, baton_sp, false);
608 SBBreakpoint::SetScriptCallbackFunction (const char *callback_function_name)
610 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
613 log->Printf ("SBBreakpoint(%p)::SetScriptCallbackFunction (callback=%s)",
614 static_cast<void*>(m_opaque_sp.get()),
615 callback_function_name);
619 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
620 BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
621 m_opaque_sp->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallbackFunction (bp_options,
622 callback_function_name);
627 SBBreakpoint::SetScriptCallbackBody (const char *callback_body_text)
629 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
632 log->Printf ("SBBreakpoint(%p)::SetScriptCallbackBody: callback body:\n%s)",
633 static_cast<void*>(m_opaque_sp.get()), callback_body_text);
638 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
639 BreakpointOptions *bp_options = m_opaque_sp->GetOptions();
640 Error error = m_opaque_sp->GetTarget().GetDebugger().GetCommandInterpreter().GetScriptInterpreter()->SetBreakpointCommandCallback (bp_options,
642 sb_error.SetError(error);
645 sb_error.SetErrorString("invalid breakpoint");
651 SBBreakpoint::AddName (const char *new_name)
653 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
656 log->Printf ("SBBreakpoint(%p)::AddName (name=%s)",
657 static_cast<void*>(m_opaque_sp.get()),
662 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
663 Error error; // Think I'm just going to swallow the error here, it's probably more annoying to have to provide it.
664 return m_opaque_sp->AddName(new_name, error);
671 SBBreakpoint::RemoveName (const char *name_to_remove)
673 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
676 log->Printf ("SBBreakpoint(%p)::RemoveName (name=%s)",
677 static_cast<void*>(m_opaque_sp.get()),
682 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
683 m_opaque_sp->RemoveName(name_to_remove);
688 SBBreakpoint::MatchesName (const char *name)
690 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
693 log->Printf ("SBBreakpoint(%p)::MatchesName (name=%s)",
694 static_cast<void*>(m_opaque_sp.get()),
699 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
700 return m_opaque_sp->MatchesName(name);
707 SBBreakpoint::GetNames (SBStringList &names)
709 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
712 log->Printf ("SBBreakpoint(%p)::GetNames ()",
713 static_cast<void*>(m_opaque_sp.get()));
717 std::lock_guard<std::recursive_mutex> guard(m_opaque_sp->GetTarget().GetAPIMutex());
718 std::vector<std::string> names_vec;
719 m_opaque_sp->GetNames(names_vec);
720 for (std::string name : names_vec)
722 names.AppendString (name.c_str());
727 lldb_private::Breakpoint *
728 SBBreakpoint::operator->() const
730 return m_opaque_sp.get();
733 lldb_private::Breakpoint *
734 SBBreakpoint::get() const
736 return m_opaque_sp.get();
740 SBBreakpoint::operator *()
745 const lldb::BreakpointSP &
746 SBBreakpoint::operator *() const
752 SBBreakpoint::EventIsBreakpointEvent (const lldb::SBEvent &event)
754 return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) != nullptr;
758 SBBreakpoint::GetBreakpointEventTypeFromEvent (const SBEvent& event)
761 return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event.GetSP());
762 return eBreakpointEventTypeInvalidType;
766 SBBreakpoint::GetBreakpointFromEvent (const lldb::SBEvent& event)
768 SBBreakpoint sb_breakpoint;
770 sb_breakpoint.m_opaque_sp = Breakpoint::BreakpointEventData::GetBreakpointFromEvent (event.GetSP());
771 return sb_breakpoint;
775 SBBreakpoint::GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx)
777 SBBreakpointLocation sb_breakpoint_loc;
779 sb_breakpoint_loc.SetLocation (Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (event.GetSP(), loc_idx));
780 return sb_breakpoint_loc;
784 SBBreakpoint::GetNumBreakpointLocationsFromEvent (const lldb::SBEvent &event)
786 uint32_t num_locations = 0;
788 num_locations = (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (event.GetSP()));
789 return num_locations;