diff options
Diffstat (limited to 'contrib/llvm/tools/lldb/source/API/SBBreakpoint.cpp')
-rw-r--r-- | contrib/llvm/tools/lldb/source/API/SBBreakpoint.cpp | 648 |
1 files changed, 648 insertions, 0 deletions
diff --git a/contrib/llvm/tools/lldb/source/API/SBBreakpoint.cpp b/contrib/llvm/tools/lldb/source/API/SBBreakpoint.cpp new file mode 100644 index 0000000..11ad149 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBBreakpoint.cpp @@ -0,0 +1,648 @@ +//===-- SBBreakpoint.cpp ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/API/SBBreakpoint.h" +#include "lldb/API/SBBreakpointLocation.h" +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBEvent.h" +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBStream.h" +#include "lldb/API/SBThread.h" + +#include "lldb/Breakpoint/Breakpoint.h" +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Breakpoint/StoppointCallbackContext.h" +#include "lldb/Core/Address.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/Stream.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/ThreadSpec.h" + + +#include "lldb/lldb-enumerations.h" + +using namespace lldb; +using namespace lldb_private; + +struct CallbackData +{ + SBBreakpoint::BreakpointHitCallback callback; + void *callback_baton; +}; + +class SBBreakpointCallbackBaton : public Baton +{ +public: + + SBBreakpointCallbackBaton (SBBreakpoint::BreakpointHitCallback callback, void *baton) : + Baton (new CallbackData) + { + CallbackData *data = (CallbackData *)m_data; + data->callback = callback; + data->callback_baton = baton; + } + + virtual ~SBBreakpointCallbackBaton() + { + CallbackData *data = (CallbackData *)m_data; + + if (data) + { + delete data; + m_data = NULL; + } + } +}; + + +SBBreakpoint::SBBreakpoint () : + m_opaque_sp () +{ +} + +SBBreakpoint::SBBreakpoint (const SBBreakpoint& rhs) : + m_opaque_sp (rhs.m_opaque_sp) +{ +} + + +SBBreakpoint::SBBreakpoint (const lldb::BreakpointSP &bp_sp) : + m_opaque_sp (bp_sp) +{ +} + +SBBreakpoint::~SBBreakpoint() +{ +} + +const SBBreakpoint & +SBBreakpoint::operator = (const SBBreakpoint& rhs) +{ + if (this != &rhs) + m_opaque_sp = rhs.m_opaque_sp; + return *this; +} + +bool +SBBreakpoint::operator == (const lldb::SBBreakpoint& rhs) +{ + if (m_opaque_sp && rhs.m_opaque_sp) + return m_opaque_sp.get() == rhs.m_opaque_sp.get(); + return false; +} + +bool +SBBreakpoint::operator != (const lldb::SBBreakpoint& rhs) +{ + if (m_opaque_sp && rhs.m_opaque_sp) + return m_opaque_sp.get() != rhs.m_opaque_sp.get(); + return (m_opaque_sp && !rhs.m_opaque_sp) || (rhs.m_opaque_sp && !m_opaque_sp); +} + +break_id_t +SBBreakpoint::GetID () const +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + break_id_t break_id = LLDB_INVALID_BREAK_ID; + if (m_opaque_sp) + break_id = m_opaque_sp->GetID(); + + if (log) + { + if (break_id == LLDB_INVALID_BREAK_ID) + log->Printf ("SBBreakpoint(%p)::GetID () => LLDB_INVALID_BREAK_ID", m_opaque_sp.get()); + else + log->Printf ("SBBreakpoint(%p)::GetID () => %u", m_opaque_sp.get(), break_id); + } + + return break_id; +} + + +bool +SBBreakpoint::IsValid() const +{ + return (bool) m_opaque_sp; +} + +void +SBBreakpoint::ClearAllBreakpointSites () +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->ClearAllBreakpointSites (); + } +} + +SBBreakpointLocation +SBBreakpoint::FindLocationByAddress (addr_t vm_addr) +{ + SBBreakpointLocation sb_bp_location; + + if (m_opaque_sp) + { + if (vm_addr != LLDB_INVALID_ADDRESS) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + Address address; + Target &target = m_opaque_sp->GetTarget(); + if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false) + { + address.SetRawAddress (vm_addr); + } + sb_bp_location.SetLocation (m_opaque_sp->FindLocationByAddress (address)); + } + } + return sb_bp_location; +} + +break_id_t +SBBreakpoint::FindLocationIDByAddress (addr_t vm_addr) +{ + break_id_t break_id = LLDB_INVALID_BREAK_ID; + + if (m_opaque_sp && vm_addr != LLDB_INVALID_ADDRESS) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + Address address; + Target &target = m_opaque_sp->GetTarget(); + if (target.GetSectionLoadList().ResolveLoadAddress (vm_addr, address) == false) + { + address.SetRawAddress (vm_addr); + } + break_id = m_opaque_sp->FindLocationIDByAddress (address); + } + + return break_id; +} + +SBBreakpointLocation +SBBreakpoint::FindLocationByID (break_id_t bp_loc_id) +{ + SBBreakpointLocation sb_bp_location; + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + sb_bp_location.SetLocation (m_opaque_sp->FindLocationByID (bp_loc_id)); + } + + return sb_bp_location; +} + +SBBreakpointLocation +SBBreakpoint::GetLocationAtIndex (uint32_t index) +{ + SBBreakpointLocation sb_bp_location; + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + sb_bp_location.SetLocation (m_opaque_sp->GetLocationAtIndex (index)); + } + + return sb_bp_location; +} + +void +SBBreakpoint::SetEnabled (bool enable) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::SetEnabled (enabled=%i)", m_opaque_sp.get(), enable); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->SetEnabled (enable); + } +} + +bool +SBBreakpoint::IsEnabled () +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + return m_opaque_sp->IsEnabled(); + } + else + return false; +} + +void +SBBreakpoint::SetOneShot (bool one_shot) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::SetOneShot (one_shot=%i)", m_opaque_sp.get(), one_shot); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->SetOneShot (one_shot); + } +} + +bool +SBBreakpoint::IsOneShot () const +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + return m_opaque_sp->IsOneShot(); + } + else + return false; +} + +bool +SBBreakpoint::IsInternal () +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + return m_opaque_sp->IsInternal(); + } + else + return false; +} + +void +SBBreakpoint::SetIgnoreCount (uint32_t count) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::SetIgnoreCount (count=%u)", m_opaque_sp.get(), count); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->SetIgnoreCount (count); + } +} + +void +SBBreakpoint::SetCondition (const char *condition) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->SetCondition (condition); + } +} + +const char * +SBBreakpoint::GetCondition () +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + return m_opaque_sp->GetConditionText (); + } + return NULL; +} + +uint32_t +SBBreakpoint::GetHitCount () const +{ + uint32_t count = 0; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + count = m_opaque_sp->GetHitCount(); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::GetHitCount () => %u", m_opaque_sp.get(), count); + + return count; +} + +uint32_t +SBBreakpoint::GetIgnoreCount () const +{ + uint32_t count = 0; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + count = m_opaque_sp->GetIgnoreCount(); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::GetIgnoreCount () => %u", m_opaque_sp.get(), count); + + return count; +} + +void +SBBreakpoint::SetThreadID (tid_t tid) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->SetThreadID (tid); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::SetThreadID (tid=0x%4.4" PRIx64 ")", m_opaque_sp.get(), tid); + +} + +tid_t +SBBreakpoint::GetThreadID () +{ + tid_t tid = LLDB_INVALID_THREAD_ID; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + tid = m_opaque_sp->GetThreadID(); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::GetThreadID () => 0x%4.4" PRIx64, m_opaque_sp.get(), tid); + return tid; +} + +void +SBBreakpoint::SetThreadIndex (uint32_t index) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::SetThreadIndex (%u)", m_opaque_sp.get(), index); + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->GetOptions()->GetThreadSpec()->SetIndex (index); + } +} + +uint32_t +SBBreakpoint::GetThreadIndex() const +{ + uint32_t thread_idx = UINT32_MAX; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate(); + if (thread_spec != NULL) + thread_idx = thread_spec->GetIndex(); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::GetThreadIndex () => %u", m_opaque_sp.get(), thread_idx); + + return thread_idx; +} + + +void +SBBreakpoint::SetThreadName (const char *thread_name) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::SetThreadName (%s)", m_opaque_sp.get(), thread_name); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->GetOptions()->GetThreadSpec()->SetName (thread_name); + } +} + +const char * +SBBreakpoint::GetThreadName () const +{ + const char *name = NULL; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate(); + if (thread_spec != NULL) + name = thread_spec->GetName(); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::GetThreadName () => %s", m_opaque_sp.get(), name); + + return name; +} + +void +SBBreakpoint::SetQueueName (const char *queue_name) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::SetQueueName (%s)", m_opaque_sp.get(), queue_name); + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + m_opaque_sp->GetOptions()->GetThreadSpec()->SetQueueName (queue_name); + } +} + +const char * +SBBreakpoint::GetQueueName () const +{ + const char *name = NULL; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + const ThreadSpec *thread_spec = m_opaque_sp->GetOptions()->GetThreadSpecNoCreate(); + if (thread_spec) + name = thread_spec->GetQueueName(); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::GetQueueName () => %s", m_opaque_sp.get(), name); + + return name; +} + +size_t +SBBreakpoint::GetNumResolvedLocations() const +{ + size_t num_resolved = 0; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + num_resolved = m_opaque_sp->GetNumResolvedLocations(); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::GetNumResolvedLocations () => %" PRIu64, m_opaque_sp.get(), (uint64_t)num_resolved); + return num_resolved; +} + +size_t +SBBreakpoint::GetNumLocations() const +{ + size_t num_locs = 0; + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + num_locs = m_opaque_sp->GetNumLocations(); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBBreakpoint(%p)::GetNumLocations () => %" PRIu64, m_opaque_sp.get(), (uint64_t)num_locs); + return num_locs; +} + +bool +SBBreakpoint::GetDescription (SBStream &s) +{ + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + s.Printf("SBBreakpoint: id = %i, ", m_opaque_sp->GetID()); + m_opaque_sp->GetResolverDescription (s.get()); + m_opaque_sp->GetFilterDescription (s.get()); + const size_t num_locations = m_opaque_sp->GetNumLocations (); + s.Printf(", locations = %" PRIu64, (uint64_t)num_locations); + return true; + } + s.Printf ("No value"); + return false; +} + +bool +SBBreakpoint::PrivateBreakpointHitCallback +( + void *baton, + StoppointCallbackContext *ctx, + lldb::user_id_t break_id, + lldb::user_id_t break_loc_id +) +{ + ExecutionContext exe_ctx (ctx->exe_ctx_ref); + BreakpointSP bp_sp(exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id)); + if (baton && bp_sp) + { + CallbackData *data = (CallbackData *)baton; + lldb_private::Breakpoint *bp = bp_sp.get(); + if (bp && data->callback) + { + Process *process = exe_ctx.GetProcessPtr(); + if (process) + { + SBProcess sb_process (process->shared_from_this()); + SBThread sb_thread; + SBBreakpointLocation sb_location; + assert (bp_sp); + sb_location.SetLocation (bp_sp->FindLocationByID (break_loc_id)); + Thread *thread = exe_ctx.GetThreadPtr(); + if (thread) + sb_thread.SetThread(thread->shared_from_this()); + + return data->callback (data->callback_baton, + sb_process, + sb_thread, + sb_location); + } + } + } + return true; // Return true if we should stop at this breakpoint +} + +void +SBBreakpoint::SetCallback (BreakpointHitCallback callback, void *baton) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + if (log) + log->Printf ("SBBreakpoint(%p)::SetCallback (callback=%p, baton=%p)", m_opaque_sp.get(), callback, baton); + + if (m_opaque_sp) + { + Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex()); + BatonSP baton_sp(new SBBreakpointCallbackBaton (callback, baton)); + m_opaque_sp->SetCallback (SBBreakpoint::PrivateBreakpointHitCallback, baton_sp, false); + } +} + + +lldb_private::Breakpoint * +SBBreakpoint::operator->() const +{ + return m_opaque_sp.get(); +} + +lldb_private::Breakpoint * +SBBreakpoint::get() const +{ + return m_opaque_sp.get(); +} + +lldb::BreakpointSP & +SBBreakpoint::operator *() +{ + return m_opaque_sp; +} + +const lldb::BreakpointSP & +SBBreakpoint::operator *() const +{ + return m_opaque_sp; +} + +bool +SBBreakpoint::EventIsBreakpointEvent (const lldb::SBEvent &event) +{ + return Breakpoint::BreakpointEventData::GetEventDataFromEvent(event.get()) != NULL; + +} + +BreakpointEventType +SBBreakpoint::GetBreakpointEventTypeFromEvent (const SBEvent& event) +{ + if (event.IsValid()) + return Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event.GetSP()); + return eBreakpointEventTypeInvalidType; +} + +SBBreakpoint +SBBreakpoint::GetBreakpointFromEvent (const lldb::SBEvent& event) +{ + SBBreakpoint sb_breakpoint; + if (event.IsValid()) + sb_breakpoint.m_opaque_sp = Breakpoint::BreakpointEventData::GetBreakpointFromEvent (event.GetSP()); + return sb_breakpoint; +} + +SBBreakpointLocation +SBBreakpoint::GetBreakpointLocationAtIndexFromEvent (const lldb::SBEvent& event, uint32_t loc_idx) +{ + SBBreakpointLocation sb_breakpoint_loc; + if (event.IsValid()) + sb_breakpoint_loc.SetLocation (Breakpoint::BreakpointEventData::GetBreakpointLocationAtIndexFromEvent (event.GetSP(), loc_idx)); + return sb_breakpoint_loc; +} + +uint32_t +SBBreakpoint::GetNumBreakpointLocationsFromEvent (const lldb::SBEvent &event) +{ + uint32_t num_locations = 0; + if (event.IsValid()) + num_locations = (Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent (event.GetSP())); + return num_locations; +} + + |