llvm-project/lldb/source/API/SBWatchpoint.cpp
Greg Clayton 5160ce5c72 <rdar://problem/13521159>
LLDB is crashing when logging is enabled from lldb-perf-clang. This has to do with the global destructor chain as the process and its threads are being torn down.

All logging channels now make one and only one instance that is kept in a global pointer which is never freed. This guarantees that logging can correctly continue as the process tears itself down.

llvm-svn: 178191
2013-03-27 23:08:40 +00:00

299 lines
6.7 KiB
C++

//===-- SBWatchpoint.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/SBWatchpoint.h"
#include "lldb/API/SBDefines.h"
#include "lldb/API/SBAddress.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBStream.h"
#include "lldb/lldb-types.h"
#include "lldb/lldb-defines.h"
#include "lldb/Breakpoint/Watchpoint.h"
#include "lldb/Breakpoint/WatchpointList.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
SBWatchpoint::SBWatchpoint () :
m_opaque_sp ()
{
}
SBWatchpoint::SBWatchpoint (const lldb::WatchpointSP &wp_sp) :
m_opaque_sp (wp_sp)
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
{
SBStream sstr;
GetDescription (sstr, lldb::eDescriptionLevelBrief);
log->Printf ("SBWatchpoint::SBWatchpoint (const lldb::WatchpointSP &wp_sp"
"=%p) => this.sp = %p (%s)", wp_sp.get(), m_opaque_sp.get(), sstr.GetData());
}
}
SBWatchpoint::SBWatchpoint(const SBWatchpoint &rhs) :
m_opaque_sp (rhs.m_opaque_sp)
{
}
const SBWatchpoint &
SBWatchpoint::operator = (const SBWatchpoint &rhs)
{
if (this != &rhs)
m_opaque_sp = rhs.m_opaque_sp;
return *this;
}
SBWatchpoint::~SBWatchpoint ()
{
}
watch_id_t
SBWatchpoint::GetID ()
{
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
watch_id = watchpoint_sp->GetID();
if (log)
{
if (watch_id == LLDB_INVALID_WATCH_ID)
log->Printf ("SBWatchpoint(%p)::GetID () => LLDB_INVALID_WATCH_ID", watchpoint_sp.get());
else
log->Printf ("SBWatchpoint(%p)::GetID () => %u", watchpoint_sp.get(), watch_id);
}
return watch_id;
}
bool
SBWatchpoint::IsValid() const
{
return (bool) m_opaque_sp;
}
SBError
SBWatchpoint::GetError ()
{
SBError sb_error;
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
sb_error.SetError(watchpoint_sp->GetError());
}
return sb_error;
}
int32_t
SBWatchpoint::GetHardwareIndex ()
{
int32_t hw_index = -1;
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
hw_index = watchpoint_sp->GetHardwareIndex();
}
return hw_index;
}
addr_t
SBWatchpoint::GetWatchAddress ()
{
addr_t ret_addr = LLDB_INVALID_ADDRESS;
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
ret_addr = watchpoint_sp->GetLoadAddress();
}
return ret_addr;
}
size_t
SBWatchpoint::GetWatchSize ()
{
size_t watch_size = 0;
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
watch_size = watchpoint_sp->GetByteSize();
}
return watch_size;
}
void
SBWatchpoint::SetEnabled (bool enabled)
{
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
watchpoint_sp->GetTarget().DisableWatchpointByID(watchpoint_sp->GetID());
}
}
bool
SBWatchpoint::IsEnabled ()
{
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
return watchpoint_sp->IsEnabled();
}
else
return false;
}
uint32_t
SBWatchpoint::GetHitCount ()
{
uint32_t count = 0;
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
count = watchpoint_sp->GetHitCount();
}
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
if (log)
log->Printf ("SBWatchpoint(%p)::GetHitCount () => %u", watchpoint_sp.get(), count);
return count;
}
uint32_t
SBWatchpoint::GetIgnoreCount ()
{
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
return watchpoint_sp->GetIgnoreCount();
}
else
return 0;
}
void
SBWatchpoint::SetIgnoreCount (uint32_t n)
{
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
watchpoint_sp->SetIgnoreCount (n);
}
}
const char *
SBWatchpoint::GetCondition ()
{
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
return watchpoint_sp->GetConditionText ();
}
return NULL;
}
void
SBWatchpoint::SetCondition (const char *condition)
{
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
watchpoint_sp->SetCondition (condition);
}
}
bool
SBWatchpoint::GetDescription (SBStream &description, DescriptionLevel level)
{
Stream &strm = description.ref();
lldb::WatchpointSP watchpoint_sp(GetSP());
if (watchpoint_sp)
{
Mutex::Locker api_locker (watchpoint_sp->GetTarget().GetAPIMutex());
watchpoint_sp->GetDescription (&strm, level);
strm.EOL();
}
else
strm.PutCString ("No value");
return true;
}
void
SBWatchpoint::Clear ()
{
m_opaque_sp.reset();
}
lldb::WatchpointSP
SBWatchpoint::GetSP () const
{
return m_opaque_sp;
}
void
SBWatchpoint::SetSP (const lldb::WatchpointSP &sp)
{
m_opaque_sp = sp;
}
bool
SBWatchpoint::EventIsWatchpointEvent (const lldb::SBEvent &event)
{
return Watchpoint::WatchpointEventData::GetEventDataFromEvent(event.get()) != NULL;
}
WatchpointEventType
SBWatchpoint::GetWatchpointEventTypeFromEvent (const SBEvent& event)
{
if (event.IsValid())
return Watchpoint::WatchpointEventData::GetWatchpointEventTypeFromEvent (event.GetSP());
return eWatchpointEventTypeInvalidType;
}
SBWatchpoint
SBWatchpoint::GetWatchpointFromEvent (const lldb::SBEvent& event)
{
SBWatchpoint sb_watchpoint;
if (event.IsValid())
sb_watchpoint.m_opaque_sp = Watchpoint::WatchpointEventData::GetWatchpointFromEvent (event.GetSP());
return sb_watchpoint;
}