Files
llvm/lldb/source/API/SBError.cpp
Greg Clayton 8f343b09e9 Added support for loading and unloading shared libraries. This was done by
adding support into lldb_private::Process:

    virtual uint32_t
    lldb_private::Process::LoadImage (const FileSpec &image_spec, 
                                      Error &error);

    virtual Error
    lldb_private::Process::UnloadImage (uint32_t image_token);

There is a default implementation that should work for both linux and MacOSX.
This ability has also been exported through the SBProcess API:

    uint32_t
    lldb::SBProcess::LoadImage (lldb::SBFileSpec &image_spec, 
                                lldb::SBError &error);

    lldb::SBError
    lldb::SBProcess::UnloadImage (uint32_t image_token);

Modified the DynamicLoader plug-in interface to require it to be able to 
tell us if it is currently possible to load/unload a shared library:

    virtual lldb_private::Error
    DynamicLoader::CanLoadImage () = 0;

This way the dynamic loader plug-ins are allows to veto whether we can 
currently load a shared library since the dynamic loader might know if it is
currenlty loading/unloading shared libraries. It might also know about the
current host system and know where to check to make sure runtime or malloc
locks are currently being held.

Modified the expression parser to have ClangUserExpression::Evaluate() be
the one that causes the dynamic checkers to be loaded instead of other code
that shouldn't have to worry about it.

llvm-svn: 118227
2010-11-04 01:54:29 +00:00

253 lines
4.7 KiB
C++

//===-- SBError.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/SBError.h"
#include "lldb/API/SBStream.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
#include <stdarg.h>
using namespace lldb;
using namespace lldb_private;
SBError::SBError () :
m_opaque_ap ()
{
}
SBError::SBError (const SBError &rhs) :
m_opaque_ap ()
{
if (rhs.IsValid())
m_opaque_ap.reset (new Error(*rhs));
}
SBError::~SBError()
{
}
const SBError &
SBError::operator = (const SBError &rhs)
{
if (rhs.IsValid())
{
if (m_opaque_ap.get())
*m_opaque_ap = *rhs;
else
m_opaque_ap.reset (new Error(*rhs));
}
else
m_opaque_ap.reset();
return *this;
}
const char *
SBError::GetCString () const
{
if (m_opaque_ap.get())
return m_opaque_ap->AsCString();
return NULL;
}
void
SBError::Clear ()
{
if (m_opaque_ap.get())
m_opaque_ap->Clear();
}
bool
SBError::Fail () const
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
bool ret_value = false;
if (m_opaque_ap.get())
ret_value = m_opaque_ap->Fail();
if (log)
log->Printf ("SBError(%p)::Fail () => %i", m_opaque_ap.get(), ret_value);
return ret_value;
}
bool
SBError::Success () const
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
bool ret_value = false;
if (m_opaque_ap.get())
ret_value = m_opaque_ap->Success();
if (log)
log->Printf ("SBError(%p)::Success () => %i", m_opaque_ap.get(), ret_value);
return ret_value;
}
uint32_t
SBError::GetError () const
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
uint32_t err = 0;
if (m_opaque_ap.get())
err = m_opaque_ap->GetError();
if (log)
log->Printf ("SBError(%p)::GetError () => 0x%8.8x", m_opaque_ap.get(), err);
return err;
}
ErrorType
SBError::GetType () const
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
ErrorType err_type = eErrorTypeInvalid;
if (m_opaque_ap.get())
err_type = m_opaque_ap->GetType();
if (log)
log->Printf ("SBError(%p)::GetType () => %i", m_opaque_ap.get(), err_type);
return err_type;
}
void
SBError::SetError (uint32_t err, ErrorType type)
{
CreateIfNeeded ();
m_opaque_ap->SetError (err, type);
}
void
SBError::SetError (const Error &lldb_error)
{
CreateIfNeeded ();
*m_opaque_ap = lldb_error;
}
void
SBError::SetErrorToErrno ()
{
CreateIfNeeded ();
m_opaque_ap->SetErrorToErrno ();
}
void
SBError::SetErrorToGenericError ()
{
CreateIfNeeded ();
m_opaque_ap->SetErrorToErrno ();
}
void
SBError::SetErrorString (const char *err_str)
{
CreateIfNeeded ();
m_opaque_ap->SetErrorString (err_str);
}
int
SBError::SetErrorStringWithFormat (const char *format, ...)
{
CreateIfNeeded ();
va_list args;
va_start (args, format);
int num_chars = m_opaque_ap->SetErrorStringWithVarArg (format, args);
va_end (args);
return num_chars;
}
bool
SBError::IsValid () const
{
return m_opaque_ap.get() != NULL;
}
void
SBError::CreateIfNeeded ()
{
if (m_opaque_ap.get() == NULL)
m_opaque_ap.reset(new Error ());
}
lldb_private::Error *
SBError::operator->()
{
return m_opaque_ap.get();
}
lldb_private::Error *
SBError::get()
{
return m_opaque_ap.get();
}
lldb_private::Error &
SBError::ref()
{
CreateIfNeeded();
return *m_opaque_ap;
}
const lldb_private::Error &
SBError::operator*() const
{
// Be sure to call "IsValid()" before calling this function or it will crash
return *m_opaque_ap;
}
bool
SBError::GetDescription (SBStream &description)
{
if (m_opaque_ap.get())
{
if (Success())
description.Printf ("Status: Success");
else
{
const char * err_string = GetCString();
description.Printf ("Status: Error: %s", (err_string != NULL ? err_string : ""));
}
}
else
description.Printf ("No value");
return true;
}
bool
SBError::GetDescription (SBStream &description) const
{
if (m_opaque_ap.get())
{
if (Success())
description.Printf ("Status: Success");
else
{
const char * err_string = GetCString();
description.Printf ("Status: Error: %s", (err_string != NULL ? err_string : ""));
}
}
else
description.Printf ("No value");
return true;
}