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
246 lines
5.4 KiB
C++
246 lines
5.4 KiB
C++
//===-- SBEvent.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/lldb-python.h"
|
|
|
|
#include "lldb/API/SBEvent.h"
|
|
#include "lldb/API/SBBroadcaster.h"
|
|
#include "lldb/API/SBStream.h"
|
|
|
|
#include "lldb/Core/Event.h"
|
|
#include "lldb/Core/Stream.h"
|
|
#include "lldb/Core/StreamFile.h"
|
|
#include "lldb/Core/ConstString.h"
|
|
#include "lldb/Target/Process.h"
|
|
#include "lldb/Breakpoint/Breakpoint.h"
|
|
#include "lldb/Interpreter/CommandInterpreter.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
|
|
SBEvent::SBEvent () :
|
|
m_event_sp (),
|
|
m_opaque_ptr (NULL)
|
|
{
|
|
}
|
|
|
|
SBEvent::SBEvent (uint32_t event_type, const char *cstr, uint32_t cstr_len) :
|
|
m_event_sp (new Event (event_type, new EventDataBytes (cstr, cstr_len))),
|
|
m_opaque_ptr (m_event_sp.get())
|
|
{
|
|
}
|
|
|
|
SBEvent::SBEvent (EventSP &event_sp) :
|
|
m_event_sp (event_sp),
|
|
m_opaque_ptr (event_sp.get())
|
|
{
|
|
}
|
|
|
|
SBEvent::SBEvent (const SBEvent &rhs) :
|
|
m_event_sp (rhs.m_event_sp),
|
|
m_opaque_ptr (rhs.m_opaque_ptr)
|
|
{
|
|
|
|
}
|
|
|
|
const SBEvent &
|
|
SBEvent::operator = (const SBEvent &rhs)
|
|
{
|
|
if (this != &rhs)
|
|
{
|
|
m_event_sp = rhs.m_event_sp;
|
|
m_opaque_ptr = rhs.m_opaque_ptr;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
SBEvent::~SBEvent()
|
|
{
|
|
}
|
|
|
|
const char *
|
|
SBEvent::GetDataFlavor ()
|
|
{
|
|
Event *lldb_event = get();
|
|
if (lldb_event)
|
|
{
|
|
EventData *event_data = lldb_event->GetData();
|
|
if (event_data)
|
|
return lldb_event->GetData()->GetFlavor().AsCString();
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
uint32_t
|
|
SBEvent::GetType () const
|
|
{
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
|
|
|
const Event *lldb_event = get();
|
|
uint32_t event_type = 0;
|
|
if (lldb_event)
|
|
event_type = lldb_event->GetType();
|
|
|
|
if (log)
|
|
{
|
|
StreamString sstr;
|
|
if (lldb_event && lldb_event->GetBroadcaster() && lldb_event->GetBroadcaster()->GetEventNames(sstr, event_type, true))
|
|
log->Printf ("SBEvent(%p)::GetType () => 0x%8.8x (%s)", get(), event_type, sstr.GetData());
|
|
else
|
|
log->Printf ("SBEvent(%p)::GetType () => 0x%8.8x", get(), event_type);
|
|
|
|
}
|
|
|
|
return event_type;
|
|
}
|
|
|
|
SBBroadcaster
|
|
SBEvent::GetBroadcaster () const
|
|
{
|
|
SBBroadcaster broadcaster;
|
|
const Event *lldb_event = get();
|
|
if (lldb_event)
|
|
broadcaster.reset (lldb_event->GetBroadcaster(), false);
|
|
return broadcaster;
|
|
}
|
|
|
|
const char *
|
|
SBEvent::GetBroadcasterClass () const
|
|
{
|
|
const Event *lldb_event = get();
|
|
if (lldb_event)
|
|
return lldb_event->GetBroadcaster()->GetBroadcasterClass().AsCString();
|
|
else
|
|
return "unknown class";
|
|
}
|
|
|
|
bool
|
|
SBEvent::BroadcasterMatchesPtr (const SBBroadcaster *broadcaster)
|
|
{
|
|
if (broadcaster)
|
|
return BroadcasterMatchesRef (*broadcaster);
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
SBEvent::BroadcasterMatchesRef (const SBBroadcaster &broadcaster)
|
|
{
|
|
|
|
Event *lldb_event = get();
|
|
bool success = false;
|
|
if (lldb_event)
|
|
success = lldb_event->BroadcasterIs (broadcaster.get());
|
|
|
|
// For logging, this gets a little chatty so only enable this when verbose logging is on
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API | LIBLLDB_LOG_VERBOSE));
|
|
if (log)
|
|
log->Printf ("SBEvent(%p)::BroadcasterMatchesRef (SBBroadcaster(%p): %s) => %i",
|
|
get(),
|
|
broadcaster.get(),
|
|
broadcaster.GetName(),
|
|
success);
|
|
|
|
return success;
|
|
}
|
|
|
|
void
|
|
SBEvent::Clear()
|
|
{
|
|
Event *lldb_event = get();
|
|
if (lldb_event)
|
|
lldb_event->Clear();
|
|
}
|
|
|
|
EventSP &
|
|
SBEvent::GetSP () const
|
|
{
|
|
return m_event_sp;
|
|
}
|
|
|
|
Event *
|
|
SBEvent::get() const
|
|
{
|
|
// There is a dangerous accessor call GetSharedPtr which can be used, so if
|
|
// we have anything valid in m_event_sp, we must use that since if it gets
|
|
// used by a function that puts something in there, then it won't update
|
|
// m_opaque_ptr...
|
|
if (m_event_sp)
|
|
m_opaque_ptr = m_event_sp.get();
|
|
|
|
return m_opaque_ptr;
|
|
}
|
|
|
|
void
|
|
SBEvent::reset (EventSP &event_sp)
|
|
{
|
|
m_event_sp = event_sp;
|
|
m_opaque_ptr = m_event_sp.get();
|
|
}
|
|
|
|
void
|
|
SBEvent::reset (Event* event_ptr)
|
|
{
|
|
m_opaque_ptr = event_ptr;
|
|
m_event_sp.reset();
|
|
}
|
|
|
|
bool
|
|
SBEvent::IsValid() const
|
|
{
|
|
// Do NOT use m_opaque_ptr directly!!! Must use the SBEvent::get()
|
|
// accessor. See comments in SBEvent::get()....
|
|
return SBEvent::get() != NULL;
|
|
|
|
}
|
|
|
|
const char *
|
|
SBEvent::GetCStringFromEvent (const SBEvent &event)
|
|
{
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
|
|
|
if (log)
|
|
log->Printf ("SBEvent(%p)::GetCStringFromEvent () => \"%s\"",
|
|
event.get(),
|
|
reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event.get())));
|
|
|
|
return reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event.get()));
|
|
}
|
|
|
|
|
|
bool
|
|
SBEvent::GetDescription (SBStream &description)
|
|
{
|
|
Stream &strm = description.ref();
|
|
|
|
if (get())
|
|
{
|
|
m_opaque_ptr->Dump (&strm);
|
|
}
|
|
else
|
|
strm.PutCString ("No value");
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
SBEvent::GetDescription (SBStream &description) const
|
|
{
|
|
Stream &strm = description.ref();
|
|
|
|
if (get())
|
|
{
|
|
m_opaque_ptr->Dump (&strm);
|
|
}
|
|
else
|
|
strm.PutCString ("No value");
|
|
|
|
return true;
|
|
}
|