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
217 lines
5.1 KiB
C++
217 lines
5.1 KiB
C++
//===-- SBInputReader.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-enumerations.h"
|
|
|
|
#include "lldb/API/SBDebugger.h"
|
|
#include "lldb/API/SBError.h"
|
|
#include "lldb/API/SBInputReader.h"
|
|
#include "lldb/API/SBStream.h"
|
|
#include "lldb/API/SBStringList.h"
|
|
#include "lldb/Core/InputReader.h"
|
|
#include "lldb/Core/Log.h"
|
|
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
SBInputReader::SBInputReader () :
|
|
m_opaque_sp (),
|
|
m_callback_function (NULL),
|
|
m_callback_baton (NULL)
|
|
|
|
{
|
|
}
|
|
|
|
SBInputReader::SBInputReader (const lldb::InputReaderSP &reader_sp) :
|
|
m_opaque_sp (reader_sp)
|
|
{
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
|
|
|
if (log)
|
|
log->Printf ("SBInputReader::SBInputReader (reader_sp=%p) => SBInputReader(%p)", reader_sp.get(),
|
|
m_opaque_sp.get());
|
|
}
|
|
|
|
SBInputReader::SBInputReader (const SBInputReader &rhs) :
|
|
m_opaque_sp (rhs.m_opaque_sp)
|
|
{
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
|
|
|
if (log)
|
|
log->Printf("SBInputReader::SBInputReader (rhs.sp=%p) => SBInputReader(%p)",
|
|
rhs.m_opaque_sp.get(), m_opaque_sp.get());
|
|
}
|
|
|
|
SBInputReader::~SBInputReader ()
|
|
{
|
|
}
|
|
|
|
size_t
|
|
SBInputReader::PrivateCallback
|
|
(
|
|
void *baton,
|
|
InputReader &reader,
|
|
lldb::InputReaderAction notification,
|
|
const char *bytes,
|
|
size_t bytes_len
|
|
)
|
|
{
|
|
SBInputReader *sb_reader = (SBInputReader *)baton;
|
|
return sb_reader->m_callback_function (sb_reader->m_callback_baton,
|
|
sb_reader,
|
|
notification,
|
|
bytes,
|
|
bytes_len);
|
|
}
|
|
|
|
SBError
|
|
SBInputReader::Initialize
|
|
(
|
|
SBDebugger &debugger,
|
|
Callback callback_function,
|
|
void *callback_baton,
|
|
lldb::InputReaderGranularity granularity,
|
|
const char *end_token,
|
|
const char *prompt,
|
|
bool echo
|
|
)
|
|
{
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
|
|
|
if (log)
|
|
log->Printf("SBInputReader(%p)::Initialize (SBDebugger(%p), callback_function=%p, callback_baton=%p, "
|
|
"granularity=%s, end_token=\"%s\", prompt=\"%s\", echo=%i)",
|
|
m_opaque_sp.get(),
|
|
debugger.get(),
|
|
callback_function,
|
|
callback_baton,
|
|
InputReader::GranularityAsCString (granularity), end_token, prompt,
|
|
echo);
|
|
|
|
SBError sb_error;
|
|
m_opaque_sp.reset (new InputReader (debugger.ref()));
|
|
|
|
m_callback_function = callback_function;
|
|
m_callback_baton = callback_baton;
|
|
|
|
if (m_opaque_sp)
|
|
{
|
|
sb_error.SetError (m_opaque_sp->Initialize (SBInputReader::PrivateCallback,
|
|
this,
|
|
granularity,
|
|
end_token,
|
|
prompt,
|
|
echo));
|
|
}
|
|
|
|
if (sb_error.Fail())
|
|
{
|
|
m_opaque_sp.reset ();
|
|
m_callback_function = NULL;
|
|
m_callback_baton = NULL;
|
|
}
|
|
|
|
if (log)
|
|
{
|
|
SBStream sstr;
|
|
sb_error.GetDescription (sstr);
|
|
log->Printf ("SBInputReader(%p)::Initialize (...) => SBError(%p): %s", m_opaque_sp.get(),
|
|
sb_error.get(), sstr.GetData());
|
|
}
|
|
|
|
return sb_error;
|
|
}
|
|
|
|
bool
|
|
SBInputReader::IsValid () const
|
|
{
|
|
return (m_opaque_sp.get() != NULL);
|
|
}
|
|
|
|
const SBInputReader &
|
|
SBInputReader::operator = (const SBInputReader &rhs)
|
|
{
|
|
if (this != &rhs)
|
|
m_opaque_sp = rhs.m_opaque_sp;
|
|
return *this;
|
|
}
|
|
|
|
InputReader *
|
|
SBInputReader::operator->() const
|
|
{
|
|
return m_opaque_sp.get();
|
|
}
|
|
|
|
lldb::InputReaderSP &
|
|
SBInputReader::operator *()
|
|
{
|
|
return m_opaque_sp;
|
|
}
|
|
|
|
const lldb::InputReaderSP &
|
|
SBInputReader::operator *() const
|
|
{
|
|
return m_opaque_sp;
|
|
}
|
|
|
|
InputReader *
|
|
SBInputReader::get() const
|
|
{
|
|
return m_opaque_sp.get();
|
|
}
|
|
|
|
InputReader &
|
|
SBInputReader::ref() const
|
|
{
|
|
assert (m_opaque_sp.get());
|
|
return *m_opaque_sp;
|
|
}
|
|
|
|
bool
|
|
SBInputReader::IsDone () const
|
|
{
|
|
if (m_opaque_sp)
|
|
return m_opaque_sp->IsDone();
|
|
else
|
|
return true;
|
|
}
|
|
|
|
void
|
|
SBInputReader::SetIsDone (bool value)
|
|
{
|
|
if (m_opaque_sp)
|
|
m_opaque_sp->SetIsDone (value);
|
|
}
|
|
|
|
bool
|
|
SBInputReader::IsActive () const
|
|
{
|
|
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
|
|
|
bool ret_value = false;
|
|
if (m_opaque_sp)
|
|
ret_value = m_opaque_sp->IsActive();
|
|
|
|
if (log)
|
|
log->Printf ("SBInputReader(%p)::IsActive () => %i", m_opaque_sp.get(), ret_value);
|
|
|
|
return ret_value;
|
|
}
|
|
|
|
InputReaderGranularity
|
|
SBInputReader::GetGranularity ()
|
|
{
|
|
if (m_opaque_sp)
|
|
return m_opaque_sp->GetGranularity();
|
|
else
|
|
return eInputReaderGranularityInvalid;
|
|
}
|