diff options
author | Jim Ingham <jingham@apple.com> | 2016-09-14 19:07:35 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2016-09-14 19:07:35 +0000 |
commit | 01f166647195b7ffff11d270648a679fb7b65bf1 (patch) | |
tree | 368f3c232731851a4f0a9b3d5e5038669aed6af0 /lldb/source/API | |
parent | db30877477e0c6434fd4a62ada3cd7916a79efa5 (diff) | |
download | bcm5719-llvm-01f166647195b7ffff11d270648a679fb7b65bf1.tar.gz bcm5719-llvm-01f166647195b7ffff11d270648a679fb7b65bf1.zip |
Add SB API's for writing breakpoints to & creating the from a file.
Moved the guts of the code from CommandObjectBreakpoint to Target (should
have done it that way in the first place.) Added an SBBreakpointList class
so there's a way to specify which breakpoints to serialize and to report the
deserialized breakpoints.
<rdar://problem/12611863>
llvm-svn: 281520
Diffstat (limited to 'lldb/source/API')
-rw-r--r-- | lldb/source/API/SBBreakpoint.cpp | 126 | ||||
-rw-r--r-- | lldb/source/API/SBTarget.cpp | 52 |
2 files changed, 178 insertions, 0 deletions
diff --git a/lldb/source/API/SBBreakpoint.cpp b/lldb/source/API/SBBreakpoint.cpp index bbdb23766cc..800ad0a277f 100644 --- a/lldb/source/API/SBBreakpoint.cpp +++ b/lldb/source/API/SBBreakpoint.cpp @@ -21,6 +21,7 @@ #include "lldb/API/SBThread.h" #include "lldb/Breakpoint/Breakpoint.h" +#include "lldb/Breakpoint/BreakpointIDList.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/Address.h" @@ -678,3 +679,128 @@ SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) { event.GetSP())); return num_locations; } + +// This is simple collection of breakpoint id's and their target. +class lldb::SBBreakpointListImpl { +public: + SBBreakpointListImpl(SBTarget &target) : m_target_wp() { + if (target.IsValid()) + m_target_wp = target.GetSP(); + } + + ~SBBreakpointListImpl() = default; + + size_t GetSize() { return m_break_ids.size(); } + + BreakpointSP GetBreakpointAtIndex(size_t idx) { + if (idx >= m_break_ids.size()) + return BreakpointSP(); + TargetSP target_sp = m_target_wp.lock(); + if (!target_sp) + return BreakpointSP(); + lldb::break_id_t bp_id = m_break_ids[idx]; + return target_sp->GetBreakpointList().FindBreakpointByID(bp_id); + } + + bool Append(Breakpoint &bkpt) { + TargetSP target_sp = m_target_wp.lock(); + if (!target_sp) + return false; + if (bkpt.GetTargetSP() != target_sp) + return false; + m_break_ids.push_back(bkpt.GetID()); + return true; + } + + bool AppendIfUnique(Breakpoint &bkpt) { + TargetSP target_sp = m_target_wp.lock(); + if (!target_sp) + return false; + if (bkpt.GetTargetSP() != target_sp) + return false; + lldb::break_id_t bp_id = bkpt.GetID(); + if (find(m_break_ids.begin(), m_break_ids.end(), bp_id) == + m_break_ids.end()) + return false; + + m_break_ids.push_back(bkpt.GetID()); + return true; + } + + bool AppendByID(lldb::break_id_t id) { + TargetSP target_sp = m_target_wp.lock(); + if (!target_sp) + return false; + if (id == LLDB_INVALID_BREAK_ID) + return false; + m_break_ids.push_back(id); + return true; + } + + void Clear() { m_break_ids.clear(); } + + void CopyToBreakpointIDList(lldb_private::BreakpointIDList &bp_list) { + for (lldb::break_id_t id : m_break_ids) { + bp_list.AddBreakpointID(BreakpointID(id)); + } + } + + TargetSP GetTarget() { return m_target_wp.lock(); } + +private: + std::vector<lldb::break_id_t> m_break_ids; + TargetWP m_target_wp; +}; + +SBBreakpointList::SBBreakpointList(SBTarget &target) + : m_opaque_sp(new lldb::SBBreakpointListImpl(target)) {} + +SBBreakpointList::~SBBreakpointList() {} + +size_t SBBreakpointList::GetSize() const { + if (!m_opaque_sp) + return 0; + else + return m_opaque_sp->GetSize(); +} + +SBBreakpoint SBBreakpointList::GetBreakpointAtIndex(size_t idx) { + if (!m_opaque_sp) + return SBBreakpoint(); + + BreakpointSP bkpt_sp = m_opaque_sp->GetBreakpointAtIndex(idx); + return SBBreakpoint(bkpt_sp); +} + +void SBBreakpointList::Append(const SBBreakpoint &sb_bkpt) { + if (!sb_bkpt.IsValid()) + return; + if (!m_opaque_sp) + return; + m_opaque_sp->Append(*sb_bkpt.get()); +} + +void SBBreakpointList::AppendByID(lldb::break_id_t id) { + if (!m_opaque_sp) + return; + m_opaque_sp->AppendByID(id); +} + +bool SBBreakpointList::AppendIfUnique(const SBBreakpoint &sb_bkpt) { + if (!sb_bkpt.IsValid()) + return false; + if (!m_opaque_sp) + return false; + return m_opaque_sp->AppendIfUnique(*sb_bkpt.get()); +} + +void SBBreakpointList::Clear() { + if (m_opaque_sp) + m_opaque_sp->Clear(); +} + +void SBBreakpointList::CopyToBreakpointIDList( + lldb_private::BreakpointIDList &bp_id_list) { + if (m_opaque_sp) + m_opaque_sp->CopyToBreakpointIDList(bp_id_list); +} diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp index 5ada7fb8a30..66d375aa457 100644 --- a/lldb/source/API/SBTarget.cpp +++ b/lldb/source/API/SBTarget.cpp @@ -1097,6 +1097,58 @@ bool SBTarget::DeleteAllBreakpoints() { return false; } +lldb::SBError SBTarget::BreakpointsCreateFromFile(SBFileSpec &source_file, + SBBreakpointList &new_bps) { + SBError sberr; + TargetSP target_sp(GetSP()); + if (!target_sp) { + sberr.SetErrorString( + "BreakpointCreateFromFile called with invalid target."); + return sberr; + } + std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex()); + + BreakpointIDList bp_ids; + sberr.ref() = target_sp->CreateBreakpointsFromFile(source_file.ref(), bp_ids); + if (sberr.Fail()) + return sberr; + + size_t num_bkpts = bp_ids.GetSize(); + for (size_t i = 0; i < num_bkpts; i++) { + BreakpointID bp_id = bp_ids.GetBreakpointIDAtIndex(i); + new_bps.AppendByID(bp_id.GetBreakpointID()); + } + return sberr; +} + +lldb::SBError SBTarget::BreakpointsWriteToFile(SBFileSpec &dest_file) { + SBError sberr; + TargetSP target_sp(GetSP()); + if (!target_sp) { + sberr.SetErrorString("BreakpointWriteToFile called with invalid target."); + return sberr; + } + SBBreakpointList bkpt_list(*this); + return BreakpointsWriteToFile(dest_file, bkpt_list); +} + +lldb::SBError SBTarget::BreakpointsWriteToFile(SBFileSpec &dest_file, + SBBreakpointList &bkpt_list) { + SBError sberr; + TargetSP target_sp(GetSP()); + if (!target_sp) { + sberr.SetErrorString("BreakpointWriteToFile called with invalid target."); + return sberr; + } + + std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex()); + BreakpointIDList bp_id_list; + bkpt_list.CopyToBreakpointIDList(bp_id_list); + sberr.ref() = + target_sp->SerializeBreakpointsToFile(dest_file.ref(), bp_id_list); + return sberr; +} + uint32_t SBTarget::GetNumWatchpoints() const { TargetSP target_sp(GetSP()); if (target_sp) { |