//===-- SBTarget.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/SBTarget.h"

#include "lldb/lldb-public.h"

#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBBreakpoint.h"
#include "lldb/API/SBExpressionOptions.h"
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBListener.h"
#include "lldb/API/SBModule.h"
#include "lldb/API/SBModuleSpec.h"
#include "lldb/API/SBSourceManager.h"
#include "lldb/API/SBProcess.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBSymbolContextList.h"
#include "lldb/Breakpoint/BreakpointID.h"
#include "lldb/Breakpoint/BreakpointIDList.h"
#include "lldb/Breakpoint/BreakpointList.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/AddressResolver.h"
#include "lldb/Core/AddressResolverName.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/SearchFilter.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/STLUtils.h"
#include "lldb/Core/ValueObjectList.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/TargetList.h"

#include "lldb/Interpreter/CommandReturnObject.h"
#include "../source/Commands/CommandObjectBreakpoint.h"


using namespace lldb;
using namespace lldb_private;

#define DEFAULT_DISASM_BYTE_SIZE 32

SBLaunchInfo::SBLaunchInfo (const char **argv) : 
    m_opaque_sp(new ProcessLaunchInfo())
{
    m_opaque_sp->GetFlags().Reset (eLaunchFlagDebug | eLaunchFlagDisableASLR);
    if (argv && argv[0])
        m_opaque_sp->GetArguments().SetArguments(argv);
}

SBLaunchInfo::~SBLaunchInfo()
{
}

lldb_private::ProcessLaunchInfo &
SBLaunchInfo::ref ()
{
    return *m_opaque_sp;
}


uint32_t
SBLaunchInfo::GetUserID()
{
    return m_opaque_sp->GetUserID();
}

uint32_t
SBLaunchInfo::GetGroupID()
{
    return m_opaque_sp->GetGroupID();
}

bool
SBLaunchInfo::UserIDIsValid ()
{
    return m_opaque_sp->UserIDIsValid();
}

bool
SBLaunchInfo::GroupIDIsValid ()
{
    return m_opaque_sp->GroupIDIsValid();
}

void
SBLaunchInfo::SetUserID (uint32_t uid)
{
    m_opaque_sp->SetUserID (uid);
}

void
SBLaunchInfo::SetGroupID (uint32_t gid)
{
    m_opaque_sp->SetGroupID (gid);
}

uint32_t
SBLaunchInfo::GetNumArguments ()
{
    return m_opaque_sp->GetArguments().GetArgumentCount();
}

const char *
SBLaunchInfo::GetArgumentAtIndex (uint32_t idx)
{
    return m_opaque_sp->GetArguments().GetArgumentAtIndex(idx);
}

void
SBLaunchInfo::SetArguments (const char **argv, bool append)
{
    if (append)
    {
        if (argv)
            m_opaque_sp->GetArguments().AppendArguments(argv);
    }
    else
    {
        if (argv)
            m_opaque_sp->GetArguments().SetArguments(argv);
        else
            m_opaque_sp->GetArguments().Clear();
    }
}

uint32_t
SBLaunchInfo::GetNumEnvironmentEntries ()
{
    return m_opaque_sp->GetEnvironmentEntries().GetArgumentCount();
}

const char *
SBLaunchInfo::GetEnvironmentEntryAtIndex (uint32_t idx)
{
    return m_opaque_sp->GetEnvironmentEntries().GetArgumentAtIndex(idx);
}

void
SBLaunchInfo::SetEnvironmentEntries (const char **envp, bool append)
{
    if (append)
    {
        if (envp)
            m_opaque_sp->GetEnvironmentEntries().AppendArguments(envp);
    }
    else
    {
        if (envp)
            m_opaque_sp->GetEnvironmentEntries().SetArguments(envp);
        else
            m_opaque_sp->GetEnvironmentEntries().Clear();
    }
}

void
SBLaunchInfo::Clear ()
{
    m_opaque_sp->Clear();
}

const char *
SBLaunchInfo::GetWorkingDirectory () const
{
    return m_opaque_sp->GetWorkingDirectory();
}

void
SBLaunchInfo::SetWorkingDirectory (const char *working_dir)
{
    m_opaque_sp->SetWorkingDirectory(working_dir);
}

uint32_t
SBLaunchInfo::GetLaunchFlags ()
{
    return m_opaque_sp->GetFlags().Get();
}

void
SBLaunchInfo::SetLaunchFlags (uint32_t flags)
{
    m_opaque_sp->GetFlags().Reset(flags);
}

const char *
SBLaunchInfo::GetProcessPluginName ()
{
    return m_opaque_sp->GetProcessPluginName();
}

void
SBLaunchInfo::SetProcessPluginName (const char *plugin_name)
{
    return m_opaque_sp->SetProcessPluginName (plugin_name);
}

const char *
SBLaunchInfo::GetShell ()
{
    return m_opaque_sp->GetShell();
}

void
SBLaunchInfo::SetShell (const char * path)
{
    m_opaque_sp->SetShell (path);
}

uint32_t
SBLaunchInfo::GetResumeCount ()
{
    return m_opaque_sp->GetResumeCount();
}

void
SBLaunchInfo::SetResumeCount (uint32_t c)
{
    m_opaque_sp->SetResumeCount (c);
}

bool
SBLaunchInfo::AddCloseFileAction (int fd)
{
    return m_opaque_sp->AppendCloseFileAction(fd);
}

bool
SBLaunchInfo::AddDuplicateFileAction (int fd, int dup_fd)
{
    return m_opaque_sp->AppendDuplicateFileAction(fd, dup_fd);
}

bool
SBLaunchInfo::AddOpenFileAction (int fd, const char *path, bool read, bool write)
{
    return m_opaque_sp->AppendOpenFileAction(fd, path, read, write);
}

bool
SBLaunchInfo::AddSuppressFileAction (int fd, bool read, bool write)
{
    return m_opaque_sp->AppendSuppressFileAction(fd, read, write);
}


SBAttachInfo::SBAttachInfo () :
    m_opaque_sp (new ProcessAttachInfo())
{
}

SBAttachInfo::SBAttachInfo (lldb::pid_t pid) :
    m_opaque_sp (new ProcessAttachInfo())
{
    m_opaque_sp->SetProcessID (pid);
}

SBAttachInfo::SBAttachInfo (const char *path, bool wait_for) :
    m_opaque_sp (new ProcessAttachInfo())
{
    if (path && path[0])
        m_opaque_sp->GetExecutableFile().SetFile(path, false);
    m_opaque_sp->SetWaitForLaunch (wait_for);
}

SBAttachInfo::SBAttachInfo (const SBAttachInfo &rhs) :
    m_opaque_sp (new ProcessAttachInfo())
{
    *m_opaque_sp = *rhs.m_opaque_sp;
}

SBAttachInfo::~SBAttachInfo()
{
}

lldb_private::ProcessAttachInfo &
SBAttachInfo::ref ()
{
    return *m_opaque_sp;
}

SBAttachInfo &
SBAttachInfo::operator = (const SBAttachInfo &rhs)
{
    if (this != &rhs)
        *m_opaque_sp = *rhs.m_opaque_sp;
    return *this;
}

lldb::pid_t
SBAttachInfo::GetProcessID ()
{
    return m_opaque_sp->GetProcessID();
}

void
SBAttachInfo::SetProcessID (lldb::pid_t pid)
{
    m_opaque_sp->SetProcessID (pid);
}


uint32_t
SBAttachInfo::GetResumeCount ()
{
    return m_opaque_sp->GetResumeCount();
}

void
SBAttachInfo::SetResumeCount (uint32_t c)
{
    m_opaque_sp->SetResumeCount (c);
}

const char *
SBAttachInfo::GetProcessPluginName ()
{
    return m_opaque_sp->GetProcessPluginName();
}

void
SBAttachInfo::SetProcessPluginName (const char *plugin_name)
{
    return m_opaque_sp->SetProcessPluginName (plugin_name);
}

void
SBAttachInfo::SetExecutable (const char *path)
{
    if (path && path[0])
        m_opaque_sp->GetExecutableFile().SetFile(path, false);
    else
        m_opaque_sp->GetExecutableFile().Clear();
}

void
SBAttachInfo::SetExecutable (SBFileSpec exe_file)
{
    if (exe_file.IsValid())
        m_opaque_sp->GetExecutableFile() = exe_file.ref();
    else
        m_opaque_sp->GetExecutableFile().Clear();
}

bool
SBAttachInfo::GetWaitForLaunch ()
{
    return m_opaque_sp->GetWaitForLaunch();
}

void
SBAttachInfo::SetWaitForLaunch (bool b)
{
    m_opaque_sp->SetWaitForLaunch (b);
}

bool
SBAttachInfo::GetIgnoreExisting ()
{
    return m_opaque_sp->GetIgnoreExisting();
}

void
SBAttachInfo::SetIgnoreExisting (bool b)
{
    m_opaque_sp->SetIgnoreExisting (b);
}

uint32_t
SBAttachInfo::GetUserID()
{
    return m_opaque_sp->GetUserID();
}

uint32_t
SBAttachInfo::GetGroupID()
{
    return m_opaque_sp->GetGroupID();
}

bool
SBAttachInfo::UserIDIsValid ()
{
    return m_opaque_sp->UserIDIsValid();
}

bool
SBAttachInfo::GroupIDIsValid ()
{
    return m_opaque_sp->GroupIDIsValid();
}

void
SBAttachInfo::SetUserID (uint32_t uid)
{
    m_opaque_sp->SetUserID (uid);
}

void
SBAttachInfo::SetGroupID (uint32_t gid)
{
    m_opaque_sp->SetGroupID (gid);
}

uint32_t
SBAttachInfo::GetEffectiveUserID()
{
    return m_opaque_sp->GetEffectiveUserID();
}

uint32_t
SBAttachInfo::GetEffectiveGroupID()
{
    return m_opaque_sp->GetEffectiveGroupID();
}

bool
SBAttachInfo::EffectiveUserIDIsValid ()
{
    return m_opaque_sp->EffectiveUserIDIsValid();
}

bool
SBAttachInfo::EffectiveGroupIDIsValid ()
{
    return m_opaque_sp->EffectiveGroupIDIsValid ();
}

void
SBAttachInfo::SetEffectiveUserID (uint32_t uid)
{
    m_opaque_sp->SetEffectiveUserID(uid);
}

void
SBAttachInfo::SetEffectiveGroupID (uint32_t gid)
{
    m_opaque_sp->SetEffectiveGroupID(gid);
}

lldb::pid_t
SBAttachInfo::GetParentProcessID ()
{
    return m_opaque_sp->GetParentProcessID();
}

void
SBAttachInfo::SetParentProcessID (lldb::pid_t pid)
{
    m_opaque_sp->SetParentProcessID (pid);
}

bool
SBAttachInfo::ParentProcessIDIsValid()
{
    return m_opaque_sp->ParentProcessIDIsValid();
}


//----------------------------------------------------------------------
// SBTarget constructor
//----------------------------------------------------------------------
SBTarget::SBTarget () :
    m_opaque_sp ()
{
}

SBTarget::SBTarget (const SBTarget& rhs) :
    m_opaque_sp (rhs.m_opaque_sp)
{
}

SBTarget::SBTarget(const TargetSP& target_sp) :
    m_opaque_sp (target_sp)
{
}

const SBTarget&
SBTarget::operator = (const SBTarget& rhs)
{
    if (this != &rhs)
        m_opaque_sp = rhs.m_opaque_sp;
    return *this;
}

//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
SBTarget::~SBTarget()
{
}

const char *
SBTarget::GetBroadcasterClassName ()
{
    return Target::GetStaticBroadcasterClass().AsCString();
}

bool
SBTarget::IsValid () const
{
    return m_opaque_sp.get() != NULL && m_opaque_sp->IsValid();
}

SBProcess
SBTarget::GetProcess ()
{
    SBProcess sb_process;
    ProcessSP process_sp;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        process_sp = target_sp->GetProcessSP();
        sb_process.SetSP (process_sp);
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        log->Printf ("SBTarget(%p)::GetProcess () => SBProcess(%p)", 
                     target_sp.get(), process_sp.get());
    }

    return sb_process;
}

SBDebugger
SBTarget::GetDebugger () const
{
    SBDebugger debugger;
    TargetSP target_sp(GetSP());
    if (target_sp)
        debugger.reset (target_sp->GetDebugger().shared_from_this());
    return debugger;
}

SBProcess
SBTarget::LoadCore (const char *core_file)
{
    SBProcess sb_process;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        FileSpec filespec(core_file, true);
        ProcessSP process_sp (target_sp->CreateProcess(target_sp->GetDebugger().GetListener(),
                                                       NULL,
                                                       &filespec));
        if (process_sp)
        {
            process_sp->LoadCore();
            sb_process.SetSP (process_sp);
        }
    }
    return sb_process;
}

SBProcess
SBTarget::LaunchSimple
(
    char const **argv,
    char const **envp,
    const char *working_directory
)
{
    char *stdin_path = NULL;
    char *stdout_path = NULL;
    char *stderr_path = NULL;
    uint32_t launch_flags = 0;
    bool stop_at_entry = false;
    SBError error;
    SBListener listener = GetDebugger().GetListener();
    return Launch (listener,
                   argv,
                   envp,
                   stdin_path,
                   stdout_path,
                   stderr_path,
                   working_directory,
                   launch_flags,
                   stop_at_entry,
                   error);
}

SBProcess
SBTarget::Launch 
(
    SBListener &listener, 
    char const **argv,
    char const **envp,
    const char *stdin_path,
    const char *stdout_path,
    const char *stderr_path,
    const char *working_directory,
    uint32_t launch_flags,   // See LaunchFlags
    bool stop_at_entry,
    lldb::SBError& error
)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBProcess sb_process;
    ProcessSP process_sp;
    TargetSP target_sp(GetSP());

    if (log)
    {
        log->Printf ("SBTarget(%p)::Launch (argv=%p, envp=%p, stdin=%s, stdout=%s, stderr=%s, working-dir=%s, launch_flags=0x%x, stop_at_entry=%i, &error (%p))...",
                     target_sp.get(), 
                     argv, 
                     envp, 
                     stdin_path ? stdin_path : "NULL", 
                     stdout_path ? stdout_path : "NULL", 
                     stderr_path ? stderr_path : "NULL", 
                     working_directory ? working_directory : "NULL",
                     launch_flags, 
                     stop_at_entry, 
                     error.get());
    }

    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());

        if (getenv("LLDB_LAUNCH_FLAG_DISABLE_ASLR"))
            launch_flags |= eLaunchFlagDisableASLR;

        StateType state = eStateInvalid;
        process_sp = target_sp->GetProcessSP();
        if (process_sp)
        {
            state = process_sp->GetState();
            
            if (process_sp->IsAlive() && state != eStateConnected)
            {       
                if (state == eStateAttaching)
                    error.SetErrorString ("process attach is in progress");
                else
                    error.SetErrorString ("a process is already being debugged");
                return sb_process;
            }            
        }
        
        if (state == eStateConnected)
        {
            // If we are already connected, then we have already specified the
            // listener, so if a valid listener is supplied, we need to error out
            // to let the client know.
            if (listener.IsValid())
            {
                error.SetErrorString ("process is connected and already has a listener, pass empty listener");
                return sb_process;
            }
        }
        else
        {
            if (listener.IsValid())
                process_sp = target_sp->CreateProcess (listener.ref(), NULL, NULL);
            else
                process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL);
        }

        if (process_sp)
        {
            sb_process.SetSP (process_sp);
            if (getenv("LLDB_LAUNCH_FLAG_DISABLE_STDIO"))
                launch_flags |= eLaunchFlagDisableSTDIO;

            ProcessLaunchInfo launch_info (stdin_path, stdout_path, stderr_path, working_directory, launch_flags);
            
            Module *exe_module = target_sp->GetExecutableModulePointer();
            if (exe_module)
                launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);
            if (argv)
                launch_info.GetArguments().AppendArguments (argv);
            if (envp)
                launch_info.GetEnvironmentEntries ().SetArguments (envp);

            error.SetError (process_sp->Launch (launch_info));
            if (error.Success())
            {
                // We we are stopping at the entry point, we can return now!
                if (stop_at_entry)
                    return sb_process;
                
                // Make sure we are stopped at the entry
                StateType state = process_sp->WaitForProcessToStop (NULL);
                if (state == eStateStopped)
                {
                    // resume the process to skip the entry point
                    error.SetError (process_sp->Resume());
                    if (error.Success())
                    {
                        // If we are doing synchronous mode, then wait for the
                        // process to stop yet again!
                        if (target_sp->GetDebugger().GetAsyncExecution () == false)
                            process_sp->WaitForProcessToStop (NULL);
                    }
                }
            }
        }
        else
        {
            error.SetErrorString ("unable to create lldb_private::Process");
        }
    }
    else
    {
        error.SetErrorString ("SBTarget is invalid");
    }

    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
    if (log)
    {
        log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)", 
                     target_sp.get(), process_sp.get());
    }

    return sb_process;
}

SBProcess
SBTarget::Launch (SBLaunchInfo &sb_launch_info, SBError& error)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    
    SBProcess sb_process;
    ProcessSP process_sp;
    TargetSP target_sp(GetSP());
    
    if (log)
    {
        log->Printf ("SBTarget(%p)::Launch (launch_info, error)...", target_sp.get());
    }
    
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        StateType state = eStateInvalid;
        process_sp = target_sp->GetProcessSP();
        if (process_sp)
        {
            state = process_sp->GetState();
            
            if (process_sp->IsAlive() && state != eStateConnected)
            {       
                if (state == eStateAttaching)
                    error.SetErrorString ("process attach is in progress");
                else
                    error.SetErrorString ("a process is already being debugged");
                return sb_process;
            }            
        }
        
        if (state != eStateConnected)
            process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL);
        
        if (process_sp)
        {
            sb_process.SetSP (process_sp);
            lldb_private::ProcessLaunchInfo &launch_info = sb_launch_info.ref();

            Module *exe_module = target_sp->GetExecutableModulePointer();
            if (exe_module)
                launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true);

            const ArchSpec &arch_spec = target_sp->GetArchitecture();
            if (arch_spec.IsValid())
                launch_info.GetArchitecture () = arch_spec;
    
            error.SetError (process_sp->Launch (launch_info));
            const bool synchronous_execution = target_sp->GetDebugger().GetAsyncExecution () == false;
            if (error.Success())
            {
                if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry))
                {
                    // If we are doing synchronous mode, then wait for the initial
                    // stop to happen, else, return and let the caller watch for
                    // the stop
                    if (synchronous_execution)
                         process_sp->WaitForProcessToStop (NULL);
                    // We we are stopping at the entry point, we can return now!
                    return sb_process;
                }
                
                // Make sure we are stopped at the entry
                StateType state = process_sp->WaitForProcessToStop (NULL);
                if (state == eStateStopped)
                {
                    // resume the process to skip the entry point
                    error.SetError (process_sp->Resume());
                    if (error.Success())
                    {
                        // If we are doing synchronous mode, then wait for the
                        // process to stop yet again!
                        if (synchronous_execution)
                            process_sp->WaitForProcessToStop (NULL);
                    }
                }
            }
        }
        else
        {
            error.SetErrorString ("unable to create lldb_private::Process");
        }
    }
    else
    {
        error.SetErrorString ("SBTarget is invalid");
    }
    
    log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API);
    if (log)
    {
        log->Printf ("SBTarget(%p)::Launch (...) => SBProcess(%p)", 
                     target_sp.get(), process_sp.get());
    }
    
    return sb_process;
}

lldb::SBProcess
SBTarget::Attach (SBAttachInfo &sb_attach_info, SBError& error)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    
    SBProcess sb_process;
    ProcessSP process_sp;
    TargetSP target_sp(GetSP());
    
    if (log)
    {
        log->Printf ("SBTarget(%p)::Attach (sb_attach_info, error)...", target_sp.get());
    }
    
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        
        StateType state = eStateInvalid;
        process_sp = target_sp->GetProcessSP();
        if (process_sp)
        {
            state = process_sp->GetState();
            
            if (process_sp->IsAlive() && state != eStateConnected)
            {       
                if (state == eStateAttaching)
                    error.SetErrorString ("process attach is in progress");
                else
                    error.SetErrorString ("a process is already being debugged");
                if (log)
                {
                    log->Printf ("SBTarget(%p)::Attach (...) => error %s",
                                 target_sp.get(), error.GetCString());
                }
                return sb_process;
            }            
        }
        
        if (state != eStateConnected)
            process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL);

        if (process_sp)
        {
            ProcessAttachInfo &attach_info = sb_attach_info.ref();
            if (attach_info.ProcessIDIsValid() && !attach_info.UserIDIsValid())
            {
                PlatformSP platform_sp = target_sp->GetPlatform();
                // See if we can pre-verify if a process exists or not
                if (platform_sp && platform_sp->IsConnected())
                {
                    lldb::pid_t attach_pid = attach_info.GetProcessID();
                    ProcessInstanceInfo instance_info;
                    if (platform_sp->GetProcessInfo(attach_pid, instance_info))
                    {
                        attach_info.SetUserID(instance_info.GetEffectiveUserID());
                    }
                    else
                    {
                        error.ref().SetErrorStringWithFormat("no process found with process ID %" PRIu64, attach_pid);
                        if (log)
                        {
                            log->Printf ("SBTarget(%p)::Attach (...) => error %s",
                                         target_sp.get(), error.GetCString());
                        }
                        return sb_process;
                    }
                }
            }
            error.SetError (process_sp->Attach (attach_info));
            if (error.Success())
            {
                sb_process.SetSP (process_sp);
                // If we are doing synchronous mode, then wait for the
                // process to stop!
                if (target_sp->GetDebugger().GetAsyncExecution () == false)
                    process_sp->WaitForProcessToStop (NULL);
            }
        }
        else
        {
            error.SetErrorString ("unable to create lldb_private::Process");
        }
    }
    else
    {
        error.SetErrorString ("SBTarget is invalid");
    }
    
    if (log)
    {
        log->Printf ("SBTarget(%p)::Attach (...) => SBProcess(%p)",
                     target_sp.get(), process_sp.get());
    }
    
    return sb_process;
}


#if defined(__APPLE__)

lldb::SBProcess
SBTarget::AttachToProcessWithID (SBListener &listener,
                                ::pid_t pid,
                                 lldb::SBError& error)
{
    return AttachToProcessWithID (listener, (lldb::pid_t)pid, error);
}

#endif // #if defined(__APPLE__)

lldb::SBProcess
SBTarget::AttachToProcessWithID 
(
    SBListener &listener, 
    lldb::pid_t pid,// The process ID to attach to
    SBError& error  // An error explaining what went wrong if attach fails
)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBProcess sb_process;
    ProcessSP process_sp;
    TargetSP target_sp(GetSP());

    if (log)
    {
        log->Printf ("SBTarget(%p)::AttachToProcessWithID (listener, pid=%" PRId64 ", error)...", target_sp.get(), pid);
    }
    
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());

        StateType state = eStateInvalid;
        process_sp = target_sp->GetProcessSP();
        if (process_sp)
        {
            state = process_sp->GetState();
            
            if (process_sp->IsAlive() && state != eStateConnected)
            {       
                if (state == eStateAttaching)
                    error.SetErrorString ("process attach is in progress");
                else
                    error.SetErrorString ("a process is already being debugged");
                return sb_process;
            }            
        }

        if (state == eStateConnected)
        {
            // If we are already connected, then we have already specified the
            // listener, so if a valid listener is supplied, we need to error out
            // to let the client know.
            if (listener.IsValid())
            {
                error.SetErrorString ("process is connected and already has a listener, pass empty listener");
                return sb_process;
            }
        }
        else
        {
            if (listener.IsValid())
                process_sp = target_sp->CreateProcess (listener.ref(), NULL, NULL);
            else
                process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL);
        }
        if (process_sp)
        {
            sb_process.SetSP (process_sp);
            
            ProcessAttachInfo attach_info;
            attach_info.SetProcessID (pid);
            
            PlatformSP platform_sp = target_sp->GetPlatform();
            ProcessInstanceInfo instance_info;
            if (platform_sp->GetProcessInfo(pid, instance_info))
            {
                attach_info.SetUserID(instance_info.GetEffectiveUserID());
            }
            error.SetError (process_sp->Attach (attach_info));            
            if (error.Success())
            {
                // If we are doing synchronous mode, then wait for the
                // process to stop!
                if (target_sp->GetDebugger().GetAsyncExecution () == false)
                process_sp->WaitForProcessToStop (NULL);
            }
        }
        else
        {
            error.SetErrorString ("unable to create lldb_private::Process");
        }
    }
    else
    {
        error.SetErrorString ("SBTarget is invalid");
    }
    
    if (log)
    {
        log->Printf ("SBTarget(%p)::AttachToProcessWithID (...) => SBProcess(%p)",
                     target_sp.get(), process_sp.get());
    }
    return sb_process;
}

lldb::SBProcess
SBTarget::AttachToProcessWithName 
(
    SBListener &listener, 
    const char *name,   // basename of process to attach to
    bool wait_for,      // if true wait for a new instance of "name" to be launched
    SBError& error      // An error explaining what went wrong if attach fails
)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    
    SBProcess sb_process;
    ProcessSP process_sp;
    TargetSP target_sp(GetSP());
    
    if (log)
    {
        log->Printf ("SBTarget(%p)::AttachToProcessWithName (listener, name=%s, wait_for=%s, error)...", target_sp.get(), name, wait_for ? "true" : "false");
    }
    
    if (name && target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());

        StateType state = eStateInvalid;
        process_sp = target_sp->GetProcessSP();
        if (process_sp)
        {
            state = process_sp->GetState();
            
            if (process_sp->IsAlive() && state != eStateConnected)
            {       
                if (state == eStateAttaching)
                    error.SetErrorString ("process attach is in progress");
                else
                    error.SetErrorString ("a process is already being debugged");
                return sb_process;
            }            
        }
        
        if (state == eStateConnected)
        {
            // If we are already connected, then we have already specified the
            // listener, so if a valid listener is supplied, we need to error out
            // to let the client know.
            if (listener.IsValid())
            {
                error.SetErrorString ("process is connected and already has a listener, pass empty listener");
                return sb_process;
            }
        }
        else
        {
            if (listener.IsValid())
                process_sp = target_sp->CreateProcess (listener.ref(), NULL, NULL);
            else
                process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), NULL, NULL);
        }

        if (process_sp)
        {
            sb_process.SetSP (process_sp);
            ProcessAttachInfo attach_info;
            attach_info.GetExecutableFile().SetFile(name, false);
            attach_info.SetWaitForLaunch(wait_for);
            error.SetError (process_sp->Attach (attach_info));
            if (error.Success())
            {
                // If we are doing synchronous mode, then wait for the
                // process to stop!
                if (target_sp->GetDebugger().GetAsyncExecution () == false)
                    process_sp->WaitForProcessToStop (NULL);
            }
        }
        else
        {
            error.SetErrorString ("unable to create lldb_private::Process");
        }
    }
    else
    {
        error.SetErrorString ("SBTarget is invalid");
    }
    
    if (log)
    {
        log->Printf ("SBTarget(%p)::AttachToPorcessWithName (...) => SBProcess(%p)",
                     target_sp.get(), process_sp.get());
    }
    return sb_process;
}

lldb::SBProcess
SBTarget::ConnectRemote
(
    SBListener &listener,
    const char *url,
    const char *plugin_name,
    SBError& error
)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBProcess sb_process;
    ProcessSP process_sp;
    TargetSP target_sp(GetSP());
    
    if (log)
    {
        log->Printf ("SBTarget(%p)::ConnectRemote (listener, url=%s, plugin_name=%s, error)...", target_sp.get(), url, plugin_name);
    }
    
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        if (listener.IsValid())
            process_sp = target_sp->CreateProcess (listener.ref(), plugin_name, NULL);
        else
            process_sp = target_sp->CreateProcess (target_sp->GetDebugger().GetListener(), plugin_name, NULL);
        
        
        if (process_sp)
        {
            sb_process.SetSP (process_sp);
            error.SetError (process_sp->ConnectRemote (NULL, url));
        }
        else
        {
            error.SetErrorString ("unable to create lldb_private::Process");
        }
    }
    else
    {
        error.SetErrorString ("SBTarget is invalid");
    }
    
    if (log)
    {
        log->Printf ("SBTarget(%p)::ConnectRemote (...) => SBProcess(%p)",
                     target_sp.get(), process_sp.get());
    }
    return sb_process;
}

SBFileSpec
SBTarget::GetExecutable ()
{

    SBFileSpec exe_file_spec;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Module *exe_module = target_sp->GetExecutableModulePointer();
        if (exe_module)
            exe_file_spec.SetFileSpec (exe_module->GetFileSpec());
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        log->Printf ("SBTarget(%p)::GetExecutable () => SBFileSpec(%p)", 
                     target_sp.get(), exe_file_spec.get());
    }

    return exe_file_spec;
}

bool
SBTarget::operator == (const SBTarget &rhs) const
{
    return m_opaque_sp.get() == rhs.m_opaque_sp.get();
}

bool
SBTarget::operator != (const SBTarget &rhs) const
{
    return m_opaque_sp.get() != rhs.m_opaque_sp.get();
}

lldb::TargetSP
SBTarget::GetSP () const
{
    return m_opaque_sp;
}

void
SBTarget::SetSP (const lldb::TargetSP& target_sp)
{
    m_opaque_sp = target_sp;
}

lldb::SBAddress
SBTarget::ResolveLoadAddress (lldb::addr_t vm_addr)
{
    lldb::SBAddress sb_addr;
    Address &addr = sb_addr.ref();
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        if (target_sp->GetSectionLoadList().ResolveLoadAddress (vm_addr, addr))
            return sb_addr;
    }

    // We have a load address that isn't in a section, just return an address
    // with the offset filled in (the address) and the section set to NULL
    addr.SetRawAddress(vm_addr);
    return sb_addr;
}

SBSymbolContext
SBTarget::ResolveSymbolContextForAddress (const SBAddress& addr, uint32_t resolve_scope)
{
    SBSymbolContext sc;
    if (addr.IsValid())
    {
        TargetSP target_sp(GetSP());
        if (target_sp)
            target_sp->GetImages().ResolveSymbolContextForAddress (addr.ref(), resolve_scope, sc.ref());
    }
    return sc;
}


SBBreakpoint
SBTarget::BreakpointCreateByLocation (const char *file, uint32_t line)
{
    return SBBreakpoint(BreakpointCreateByLocation (SBFileSpec (file, false), line));
}

SBBreakpoint
SBTarget::BreakpointCreateByLocation (const SBFileSpec &sb_file_spec, uint32_t line)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp && line != 0)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        
        const LazyBool check_inlines = eLazyBoolCalculate;
        const LazyBool skip_prologue = eLazyBoolCalculate;
        const bool internal = false;
        *sb_bp = target_sp->CreateBreakpoint (NULL, *sb_file_spec, line, check_inlines, skip_prologue, internal);
    }

    if (log)
    {
        SBStream sstr;
        sb_bp.GetDescription (sstr);
        char path[PATH_MAX];
        sb_file_spec->GetPath (path, sizeof(path));
        log->Printf ("SBTarget(%p)::BreakpointCreateByLocation ( %s:%u ) => SBBreakpoint(%p): %s", 
                     target_sp.get(), 
                     path,
                     line, 
                     sb_bp.get(),
                     sstr.GetData());
    }

    return sb_bp;
}

SBBreakpoint
SBTarget::BreakpointCreateByName (const char *symbol_name, const char *module_name)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp.get())
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        
        const bool internal = false;
        const LazyBool skip_prologue = eLazyBoolCalculate;
        if (module_name && module_name[0])
        {
            FileSpecList module_spec_list;
            module_spec_list.Append (FileSpec (module_name, false));
            *sb_bp = target_sp->CreateBreakpoint (&module_spec_list, NULL, symbol_name, eFunctionNameTypeAuto, skip_prologue, internal);
        }
        else
        {
            *sb_bp = target_sp->CreateBreakpoint (NULL, NULL, symbol_name, eFunctionNameTypeAuto, skip_prologue, internal);
        }
    }
    
    if (log)
    {
        log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", module=\"%s\") => SBBreakpoint(%p)", 
                     target_sp.get(), symbol_name, module_name, sb_bp.get());
    }

    return sb_bp;
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateByName (const char *symbol_name, 
                            const SBFileSpecList &module_list, 
                            const SBFileSpecList &comp_unit_list)
{
    uint32_t name_type_mask = eFunctionNameTypeAuto;
    return BreakpointCreateByName (symbol_name, name_type_mask, module_list, comp_unit_list);
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateByName (const char *symbol_name,
                            uint32_t name_type_mask,
                            const SBFileSpecList &module_list, 
                            const SBFileSpecList &comp_unit_list)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp && symbol_name && symbol_name[0])
    {
        const bool internal = false;
        const LazyBool skip_prologue = eLazyBoolCalculate;
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        *sb_bp = target_sp->CreateBreakpoint (module_list.get(), 
                                                comp_unit_list.get(), 
                                                symbol_name, 
                                                name_type_mask, 
                                                skip_prologue,
                                                internal);
    }
    
    if (log)
    {
        log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\", name_type: %d) => SBBreakpoint(%p)", 
                     target_sp.get(), symbol_name, name_type_mask, sb_bp.get());
    }

    return sb_bp;
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateByNames (const char *symbol_names[],
                                   uint32_t num_names,
                                   uint32_t name_type_mask,
                                   const SBFileSpecList &module_list,
                                   const SBFileSpecList &comp_unit_list)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp && num_names > 0)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        const bool internal = false;
        const LazyBool skip_prologue = eLazyBoolCalculate;
        *sb_bp = target_sp->CreateBreakpoint (module_list.get(), 
                                                comp_unit_list.get(), 
                                                symbol_names,
                                                num_names,
                                                name_type_mask, 
                                                skip_prologue,
                                                internal);
    }
    
    if (log)
    {
        log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbols={", target_sp.get());
        for (uint32_t i = 0 ; i < num_names; i++)
        {
            char sep;
            if (i < num_names - 1)
                sep = ',';
            else
                sep = '}';
            if (symbol_names[i] != NULL)
                log->Printf ("\"%s\"%c ", symbol_names[i], sep);
            else
                log->Printf ("\"<NULL>\"%c ", sep);
            
        }
        log->Printf ("name_type: %d) => SBBreakpoint(%p)", name_type_mask, sb_bp.get());
    }

    return sb_bp;
}

SBBreakpoint
SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp && symbol_name_regex && symbol_name_regex[0])
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        RegularExpression regexp(symbol_name_regex);
        const bool internal = false;
        const LazyBool skip_prologue = eLazyBoolCalculate;
        
        if (module_name && module_name[0])
        {
            FileSpecList module_spec_list;
            module_spec_list.Append (FileSpec (module_name, false));
            
            *sb_bp = target_sp->CreateFuncRegexBreakpoint (&module_spec_list, NULL, regexp, skip_prologue, internal);
        }
        else
        {
            *sb_bp = target_sp->CreateFuncRegexBreakpoint (NULL, NULL, regexp, skip_prologue, internal);
        }
    }

    if (log)
    {
        log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)", 
                     target_sp.get(), symbol_name_regex, module_name, sb_bp.get());
    }

    return sb_bp;
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, 
                         const SBFileSpecList &module_list, 
                         const SBFileSpecList &comp_unit_list)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp && symbol_name_regex && symbol_name_regex[0])
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        RegularExpression regexp(symbol_name_regex);
        const bool internal = false;
        const LazyBool skip_prologue = eLazyBoolCalculate;
        
        *sb_bp = target_sp->CreateFuncRegexBreakpoint (module_list.get(), comp_unit_list.get(), regexp, skip_prologue, internal);
    }

    if (log)
    {
        log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\") => SBBreakpoint(%p)", 
                     target_sp.get(), symbol_name_regex, sb_bp.get());
    }

    return sb_bp;
}

SBBreakpoint
SBTarget::BreakpointCreateByAddress (addr_t address)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        *sb_bp = target_sp->CreateBreakpoint (address, false);
    }
    
    if (log)
    {
        log->Printf ("SBTarget(%p)::BreakpointCreateByAddress (address=%" PRIu64 ") => SBBreakpoint(%p)", target_sp.get(), (uint64_t) address, sb_bp.get());
    }

    return sb_bp;
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateBySourceRegex (const char *source_regex, const lldb::SBFileSpec &source_file, const char *module_name)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp && source_regex && source_regex[0])
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        RegularExpression regexp(source_regex);
        FileSpecList source_file_spec_list;
        source_file_spec_list.Append (source_file.ref());
        
        if (module_name && module_name[0])
        {
            FileSpecList module_spec_list;
            module_spec_list.Append (FileSpec (module_name, false));
            
            *sb_bp = target_sp->CreateSourceRegexBreakpoint (&module_spec_list, &source_file_spec_list, regexp, false);
        }
        else
        {
            *sb_bp = target_sp->CreateSourceRegexBreakpoint (NULL, &source_file_spec_list, regexp, false);
        }
    }

    if (log)
    {
        char path[PATH_MAX];
        source_file->GetPath (path, sizeof(path));
        log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\", file=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)", 
                     target_sp.get(), source_regex, path, module_name, sb_bp.get());
    }

    return sb_bp;
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateBySourceRegex (const char *source_regex, 
                               const SBFileSpecList &module_list, 
                               const lldb::SBFileSpecList &source_file_list)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp && source_regex && source_regex[0])
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        RegularExpression regexp(source_regex);
        *sb_bp = target_sp->CreateSourceRegexBreakpoint (module_list.get(), source_file_list.get(), regexp, false);
    }

    if (log)
    {
        log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\") => SBBreakpoint(%p)", 
                     target_sp.get(), source_regex, sb_bp.get());
    }

    return sb_bp;
}

lldb::SBBreakpoint
SBTarget::BreakpointCreateForException  (lldb::LanguageType language,
                               bool catch_bp,
                               bool throw_bp)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_bp;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        *sb_bp = target_sp->CreateExceptionBreakpoint (language, catch_bp, throw_bp);
    }

    if (log)
    {
        log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (Language: %s, catch: %s throw: %s) => SBBreakpoint(%p)", 
                     target_sp.get(),
                     LanguageRuntime::GetNameForLanguageType(language),
                     catch_bp ? "on" : "off",
                     throw_bp ? "on" : "off",
                     sb_bp.get());
    }

    return sb_bp;
}

uint32_t
SBTarget::GetNumBreakpoints () const
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        // The breakpoint list is thread safe, no need to lock
        return target_sp->GetBreakpointList().GetSize();
    }
    return 0;
}

SBBreakpoint
SBTarget::GetBreakpointAtIndex (uint32_t idx) const
{
    SBBreakpoint sb_breakpoint;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        // The breakpoint list is thread safe, no need to lock
        *sb_breakpoint = target_sp->GetBreakpointList().GetBreakpointAtIndex(idx);
    }
    return sb_breakpoint;
}

bool
SBTarget::BreakpointDelete (break_id_t bp_id)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    bool result = false;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        result = target_sp->RemoveBreakpointByID (bp_id);
    }

    if (log)
    {
        log->Printf ("SBTarget(%p)::BreakpointDelete (bp_id=%d) => %i", target_sp.get(), (uint32_t) bp_id, result);
    }

    return result;
}

SBBreakpoint
SBTarget::FindBreakpointByID (break_id_t bp_id)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBBreakpoint sb_breakpoint;
    TargetSP target_sp(GetSP());
    if (target_sp && bp_id != LLDB_INVALID_BREAK_ID)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        *sb_breakpoint = target_sp->GetBreakpointByID (bp_id);
    }

    if (log)
    {
        log->Printf ("SBTarget(%p)::FindBreakpointByID (bp_id=%d) => SBBreakpoint(%p)", 
                     target_sp.get(), (uint32_t) bp_id, sb_breakpoint.get());
    }

    return sb_breakpoint;
}

bool
SBTarget::EnableAllBreakpoints ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        target_sp->EnableAllBreakpoints ();
        return true;
    }
    return false;
}

bool
SBTarget::DisableAllBreakpoints ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        target_sp->DisableAllBreakpoints ();
        return true;
    }
    return false;
}

bool
SBTarget::DeleteAllBreakpoints ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        target_sp->RemoveAllBreakpoints ();
        return true;
    }
    return false;
}

uint32_t
SBTarget::GetNumWatchpoints () const
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        // The watchpoint list is thread safe, no need to lock
        return target_sp->GetWatchpointList().GetSize();
    }
    return 0;
}

SBWatchpoint
SBTarget::GetWatchpointAtIndex (uint32_t idx) const
{
    SBWatchpoint sb_watchpoint;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        // The watchpoint list is thread safe, no need to lock
        sb_watchpoint.SetSP (target_sp->GetWatchpointList().GetByIndex(idx));
    }
    return sb_watchpoint;
}

bool
SBTarget::DeleteWatchpoint (watch_id_t wp_id)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    bool result = false;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        Mutex::Locker locker;
        target_sp->GetWatchpointList().GetListMutex(locker);
        result = target_sp->RemoveWatchpointByID (wp_id);
    }

    if (log)
    {
        log->Printf ("SBTarget(%p)::WatchpointDelete (wp_id=%d) => %i", target_sp.get(), (uint32_t) wp_id, result);
    }

    return result;
}

SBWatchpoint
SBTarget::FindWatchpointByID (lldb::watch_id_t wp_id)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBWatchpoint sb_watchpoint;
    lldb::WatchpointSP watchpoint_sp;
    TargetSP target_sp(GetSP());
    if (target_sp && wp_id != LLDB_INVALID_WATCH_ID)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        Mutex::Locker locker;
        target_sp->GetWatchpointList().GetListMutex(locker);
        watchpoint_sp = target_sp->GetWatchpointList().FindByID(wp_id);
        sb_watchpoint.SetSP (watchpoint_sp);
    }

    if (log)
    {
        log->Printf ("SBTarget(%p)::FindWatchpointByID (bp_id=%d) => SBWatchpoint(%p)", 
                     target_sp.get(), (uint32_t) wp_id, watchpoint_sp.get());
    }

    return sb_watchpoint;
}

lldb::SBWatchpoint
SBTarget::WatchAddress (lldb::addr_t addr, size_t size, bool read, bool write, SBError &error)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    
    SBWatchpoint sb_watchpoint;
    lldb::WatchpointSP watchpoint_sp;
    TargetSP target_sp(GetSP());
    if (target_sp && (read || write) && addr != LLDB_INVALID_ADDRESS && size > 0)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        uint32_t watch_type = 0;
        if (read)
            watch_type |= LLDB_WATCH_TYPE_READ;
        if (write)
            watch_type |= LLDB_WATCH_TYPE_WRITE;
        if (watch_type == 0)
        {
            error.SetErrorString("Can't create a watchpoint that is neither read nor write.");
            return sb_watchpoint;
        }
        
        // Target::CreateWatchpoint() is thread safe.
        Error cw_error;
        // This API doesn't take in a type, so we can't figure out what it is.
        ClangASTType *type = NULL;
        watchpoint_sp = target_sp->CreateWatchpoint(addr, size, type, watch_type, cw_error);
        error.SetError(cw_error);
        sb_watchpoint.SetSP (watchpoint_sp);
    }
    
    if (log)
    {
        log->Printf ("SBTarget(%p)::WatchAddress (addr=0x%" PRIx64 ", 0x%u) => SBWatchpoint(%p)",
                     target_sp.get(), addr, (uint32_t) size, watchpoint_sp.get());
    }
    
    return sb_watchpoint;
}

bool
SBTarget::EnableAllWatchpoints ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        Mutex::Locker locker;
        target_sp->GetWatchpointList().GetListMutex(locker);
        target_sp->EnableAllWatchpoints ();
        return true;
    }
    return false;
}

bool
SBTarget::DisableAllWatchpoints ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        Mutex::Locker locker;
        target_sp->GetWatchpointList().GetListMutex(locker);
        target_sp->DisableAllWatchpoints ();
        return true;
    }
    return false;
}

bool
SBTarget::DeleteAllWatchpoints ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        Mutex::Locker locker;
        target_sp->GetWatchpointList().GetListMutex(locker);
        target_sp->RemoveAllWatchpoints ();
        return true;
    }
    return false;
}


lldb::SBModule
SBTarget::AddModule (const char *path,
                     const char *triple,
                     const char *uuid_cstr)
{
    return AddModule (path, triple, uuid_cstr, NULL);
}

lldb::SBModule
SBTarget::AddModule (const char *path,
                     const char *triple,
                     const char *uuid_cstr,
                     const char *symfile)
{
    lldb::SBModule sb_module;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        ModuleSpec module_spec;
        if (path)
            module_spec.GetFileSpec().SetFile(path, false);
        
        if (uuid_cstr)
            module_spec.GetUUID().SetFromCString(uuid_cstr);
        
        if (triple)
            module_spec.GetArchitecture().SetTriple (triple, target_sp->GetPlatform ().get());
        
        if (symfile)
            module_spec.GetSymbolFileSpec ().SetFile(symfile, false);

        sb_module.SetSP(target_sp->GetSharedModule (module_spec));
    }
    return sb_module;
}

lldb::SBModule
SBTarget::AddModule (const SBModuleSpec &module_spec)
{
    lldb::SBModule sb_module;
    TargetSP target_sp(GetSP());
    if (target_sp)
        sb_module.SetSP(target_sp->GetSharedModule (*module_spec.m_opaque_ap));
    return sb_module;
}

bool
SBTarget::AddModule (lldb::SBModule &module)
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        target_sp->GetImages().AppendIfNeeded (module.GetSP());
        return true;
    }
    return false;
}

uint32_t
SBTarget::GetNumModules () const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    uint32_t num = 0;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        // The module list is thread safe, no need to lock
        num = target_sp->GetImages().GetSize();
    }

    if (log)
        log->Printf ("SBTarget(%p)::GetNumModules () => %d", target_sp.get(), num);

    return num;
}

void
SBTarget::Clear ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    if (log)
        log->Printf ("SBTarget(%p)::Clear ()", m_opaque_sp.get());

    m_opaque_sp.reset();
}


SBModule
SBTarget::FindModule (const SBFileSpec &sb_file_spec)
{
    SBModule sb_module;
    TargetSP target_sp(GetSP());
    if (target_sp && sb_file_spec.IsValid())
    {
        ModuleSpec module_spec(*sb_file_spec);
        // The module list is thread safe, no need to lock
        sb_module.SetSP (target_sp->GetImages().FindFirstModule (module_spec));
    }
    return sb_module;
}

lldb::ByteOrder
SBTarget::GetByteOrder ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
        return target_sp->GetArchitecture().GetByteOrder();
    return eByteOrderInvalid;
}

const char *
SBTarget::GetTriple ()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        std::string triple (target_sp->GetArchitecture().GetTriple().str());
        // Unique the string so we don't run into ownership issues since
        // the const strings put the string into the string pool once and
        // the strings never comes out
        ConstString const_triple (triple.c_str());
        return const_triple.GetCString();
    }
    return NULL;
}

uint32_t
SBTarget::GetAddressByteSize()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
        return target_sp->GetArchitecture().GetAddressByteSize();
    return sizeof(void*);
}


SBModule
SBTarget::GetModuleAtIndex (uint32_t idx)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBModule sb_module;
    ModuleSP module_sp;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        // The module list is thread safe, no need to lock
        module_sp = target_sp->GetImages().GetModuleAtIndex(idx);
        sb_module.SetSP (module_sp);
    }

    if (log)
    {
        log->Printf ("SBTarget(%p)::GetModuleAtIndex (idx=%d) => SBModule(%p)", 
                     target_sp.get(), idx, module_sp.get());
    }

    return sb_module;
}

bool
SBTarget::RemoveModule (lldb::SBModule module)
{
    TargetSP target_sp(GetSP());
    if (target_sp)
        return target_sp->GetImages().Remove(module.GetSP());
    return false;
}


SBBroadcaster
SBTarget::GetBroadcaster () const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    TargetSP target_sp(GetSP());
    SBBroadcaster broadcaster(target_sp.get(), false);
    
    if (log)
        log->Printf ("SBTarget(%p)::GetBroadcaster () => SBBroadcaster(%p)", 
                     target_sp.get(), broadcaster.get());

    return broadcaster;
}

bool
SBTarget::GetDescription (SBStream &description, lldb::DescriptionLevel description_level)
{
    Stream &strm = description.ref();

    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        target_sp->Dump (&strm, description_level);
    }
    else
        strm.PutCString ("No value");
    
    return true;
}

lldb::SBSymbolContextList
SBTarget::FindFunctions (const char *name, uint32_t name_type_mask)
{
    lldb::SBSymbolContextList sb_sc_list;
    if (name && name[0])
    {
        TargetSP target_sp(GetSP());
        if (target_sp)
        {
            const bool symbols_ok = true;
            const bool inlines_ok = true;
            const bool append = true;
            target_sp->GetImages().FindFunctions (ConstString(name), 
                                                  name_type_mask, 
                                                  symbols_ok,
                                                  inlines_ok,
                                                  append, 
                                                  *sb_sc_list);
        }
    }
    return sb_sc_list;
}

lldb::SBType
SBTarget::FindFirstType (const char* typename_cstr)
{
    TargetSP target_sp(GetSP());
    if (typename_cstr && typename_cstr[0] && target_sp)
    {
        ConstString const_typename(typename_cstr);
        SymbolContext sc;
        const bool exact_match = false;

        const ModuleList &module_list = target_sp->GetImages();
        size_t count = module_list.GetSize();
        for (size_t idx = 0; idx < count; idx++)
        {
            ModuleSP module_sp (module_list.GetModuleAtIndex(idx));
            if (module_sp)
            {
                TypeSP type_sp (module_sp->FindFirstType(sc, const_typename, exact_match));
                if (type_sp)
                    return SBType(type_sp);
            }
        }
        
        // Didn't find the type in the symbols; try the Objective-C runtime
        // if one is installed
        
        ProcessSP process_sp(target_sp->GetProcessSP());
        
        if (process_sp)
        {
            ObjCLanguageRuntime *objc_language_runtime = process_sp->GetObjCLanguageRuntime();
            
            if (objc_language_runtime)
            {
                TypeVendor *objc_type_vendor = objc_language_runtime->GetTypeVendor();
                
                if (objc_type_vendor)
                {
                    std::vector <ClangASTType> types;
                    
                    if (objc_type_vendor->FindTypes(const_typename, true, 1, types) > 0)
                        return SBType(types[0]);
                }
            }
        }

        // No matches, search for basic typename matches
        ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
        if (clang_ast)
            return SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), const_typename));
    }
    return SBType();
}

SBType
SBTarget::GetBasicType(lldb::BasicType type)
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
        if (clang_ast)
            return SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), type));
    }
    return SBType();
}


lldb::SBTypeList
SBTarget::FindTypes (const char* typename_cstr)
{
    SBTypeList sb_type_list;
    TargetSP target_sp(GetSP());
    if (typename_cstr && typename_cstr[0] && target_sp)
    {
        ModuleList& images = target_sp->GetImages();
        ConstString const_typename(typename_cstr);
        bool exact_match = false;
        SymbolContext sc;
        TypeList type_list;
        
        uint32_t num_matches = images.FindTypes (sc,
                                                 const_typename,
                                                 exact_match,
                                                 UINT32_MAX,
                                                 type_list);
        
        if (num_matches > 0)
        {
            for (size_t idx = 0; idx < num_matches; idx++)
            {
                TypeSP type_sp (type_list.GetTypeAtIndex(idx));
                if (type_sp)
                    sb_type_list.Append(SBType(type_sp));
            }
        }
        
        // Try the Objective-C runtime if one is installed
        
        ProcessSP process_sp(target_sp->GetProcessSP());
        
        if (process_sp)
        {
            ObjCLanguageRuntime *objc_language_runtime = process_sp->GetObjCLanguageRuntime();
            
            if (objc_language_runtime)
            {
                TypeVendor *objc_type_vendor = objc_language_runtime->GetTypeVendor();
                
                if (objc_type_vendor)
                {
                    std::vector <ClangASTType> types;
                    
                    if (objc_type_vendor->FindTypes(const_typename, true, UINT32_MAX, types))
                    {
                        for (ClangASTType &type : types)
                        {
                            sb_type_list.Append(SBType(type));
                        }
                    }
                }
            }
        }
        
        if (sb_type_list.GetSize() == 0)
        {
            // No matches, search for basic typename matches
            ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
            if (clang_ast)
                sb_type_list.Append (SBType (ClangASTContext::GetBasicType (clang_ast->getASTContext(), const_typename)));
        }
    }
    return sb_type_list;
}

SBValueList
SBTarget::FindGlobalVariables (const char *name, uint32_t max_matches)
{
    SBValueList sb_value_list;
    
    TargetSP target_sp(GetSP());
    if (name && target_sp)
    {
        VariableList variable_list;
        const bool append = true;
        const uint32_t match_count = target_sp->GetImages().FindGlobalVariables (ConstString (name), 
                                                                                 append, 
                                                                                 max_matches,
                                                                                 variable_list);
        
        if (match_count > 0)
        {
            ExecutionContextScope *exe_scope = target_sp->GetProcessSP().get();
            if (exe_scope == NULL)
                exe_scope = target_sp.get();
            for (uint32_t i=0; i<match_count; ++i)
            {
                lldb::ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_scope, variable_list.GetVariableAtIndex(i)));
                if (valobj_sp)
                    sb_value_list.Append(SBValue(valobj_sp));
            }
        }
    }

    return sb_value_list;
}

lldb::SBValue
SBTarget::FindFirstGlobalVariable (const char* name)
{
    SBValueList sb_value_list(FindGlobalVariables(name, 1));
    if (sb_value_list.IsValid() && sb_value_list.GetSize() > 0)
        return sb_value_list.GetValueAtIndex(0);
    return SBValue();
}

SBSourceManager
SBTarget::GetSourceManager()
{
    SBSourceManager source_manager (*this);
    return source_manager;
}

lldb::SBInstructionList
SBTarget::ReadInstructions (lldb::SBAddress base_addr, uint32_t count)
{
    return ReadInstructions (base_addr, count, NULL);
}

lldb::SBInstructionList
SBTarget::ReadInstructions (lldb::SBAddress base_addr, uint32_t count, const char *flavor_string)
{
    SBInstructionList sb_instructions;
    
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Address *addr_ptr = base_addr.get();
        
        if (addr_ptr)
        {
            DataBufferHeap data (target_sp->GetArchitecture().GetMaximumOpcodeByteSize() * count, 0);
            bool prefer_file_cache = false;
            lldb_private::Error error;
            lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
            const size_t bytes_read = target_sp->ReadMemory(*addr_ptr,
                                                            prefer_file_cache,
                                                            data.GetBytes(),
                                                            data.GetByteSize(),
                                                            error,
                                                            &load_addr);
            const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
            sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(),
                                                                             NULL,
                                                                             flavor_string,
                                                                             *addr_ptr,
                                                                             data.GetBytes(),
                                                                             bytes_read,
                                                                             count,
                                                                             data_from_file));
        }
    }
    
    return sb_instructions;
    
}

lldb::SBInstructionList
SBTarget::GetInstructions (lldb::SBAddress base_addr, const void *buf, size_t size)
{
    return GetInstructionsWithFlavor (base_addr, NULL, buf, size);
}

lldb::SBInstructionList
SBTarget::GetInstructionsWithFlavor (lldb::SBAddress base_addr, const char *flavor_string, const void *buf, size_t size)
{
    SBInstructionList sb_instructions;
    
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        Address addr;
        
        if (base_addr.get())
            addr = *base_addr.get();
        
        const bool data_from_file = true;

        sb_instructions.SetDisassembler (Disassembler::DisassembleBytes (target_sp->GetArchitecture(),
                                                                         NULL,
                                                                         flavor_string,
                                                                         addr,
                                                                         buf,
                                                                         size,
                                                                         UINT32_MAX,
                                                                         data_from_file));
    }

    return sb_instructions;
}

lldb::SBInstructionList
SBTarget::GetInstructions (lldb::addr_t base_addr, const void *buf, size_t size)
{
    return GetInstructionsWithFlavor (ResolveLoadAddress(base_addr), NULL, buf, size);
}

lldb::SBInstructionList
SBTarget::GetInstructionsWithFlavor (lldb::addr_t base_addr, const char *flavor_string, const void *buf, size_t size)
{
    return GetInstructionsWithFlavor (ResolveLoadAddress(base_addr), flavor_string, buf, size);
}

SBError
SBTarget::SetSectionLoadAddress (lldb::SBSection section,
                                 lldb::addr_t section_base_addr)
{
    SBError sb_error;
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        if (!section.IsValid())
        {
            sb_error.SetErrorStringWithFormat ("invalid section");
        }
        else
        {
            SectionSP section_sp (section.GetSP());
            if (section_sp)
            {
                if (section_sp->IsThreadSpecific())
                {
                    sb_error.SetErrorString ("thread specific sections are not yet supported");
                }
                else
                {
                    if (target_sp->GetSectionLoadList().SetSectionLoadAddress (section_sp, section_base_addr))
                    {
                        // Flush info in the process (stack frames, etc)
                        ProcessSP process_sp (target_sp->GetProcessSP());
                        if (process_sp)
                            process_sp->Flush();
                    }
                }
            }
        }
    }
    else
    {
        sb_error.SetErrorString ("invalid target");
    }
    return sb_error;
}

SBError
SBTarget::ClearSectionLoadAddress (lldb::SBSection section)
{
    SBError sb_error;
    
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        if (!section.IsValid())
        {
            sb_error.SetErrorStringWithFormat ("invalid section");
        }
        else
        {
            if (target_sp->GetSectionLoadList().SetSectionUnloaded (section.GetSP()))
            {
                // Flush info in the process (stack frames, etc)
                ProcessSP process_sp (target_sp->GetProcessSP());
                if (process_sp)
                    process_sp->Flush();                
            }
        }
    }
    else
    {
        sb_error.SetErrorStringWithFormat ("invalid target");
    }
    return sb_error;
}

SBError
SBTarget::SetModuleLoadAddress (lldb::SBModule module, int64_t slide_offset)
{
    SBError sb_error;
    
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        ModuleSP module_sp (module.GetSP());
        if (module_sp)
        {
            bool changed = false;
            if (module_sp->SetLoadAddress (*target_sp, slide_offset, changed))
            {
                // The load was successful, make sure that at least some sections
                // changed before we notify that our module was loaded.
                if (changed)
                {
                    ModuleList module_list;
                    module_list.Append(module_sp);
                    target_sp->ModulesDidLoad (module_list);
                    // Flush info in the process (stack frames, etc)
                    ProcessSP process_sp (target_sp->GetProcessSP());
                    if (process_sp)
                        process_sp->Flush();
                }
            }
        }
        else
        {
            sb_error.SetErrorStringWithFormat ("invalid module");
        }

    }
    else
    {
        sb_error.SetErrorStringWithFormat ("invalid target");
    }
    return sb_error;
}

SBError
SBTarget::ClearModuleLoadAddress (lldb::SBModule module)
{
    SBError sb_error;
    
    char path[PATH_MAX];
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        ModuleSP module_sp (module.GetSP());
        if (module_sp)
        {
            ObjectFile *objfile = module_sp->GetObjectFile();
            if (objfile)
            {
                SectionList *section_list = objfile->GetSectionList();
                if (section_list)
                {
                    bool changed = false;
                    const size_t num_sections = section_list->GetSize();
                    for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
                    {
                        SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx));
                        if (section_sp)
                            changed |= target_sp->GetSectionLoadList().SetSectionUnloaded (section_sp) > 0;
                    }
                    if (changed)
                    {
                        // Flush info in the process (stack frames, etc)
                        ProcessSP process_sp (target_sp->GetProcessSP());
                        if (process_sp)
                            process_sp->Flush();                        
                    }
                }
                else
                {
                    module_sp->GetFileSpec().GetPath (path, sizeof(path));
                    sb_error.SetErrorStringWithFormat ("no sections in object file '%s'", path);
                }
            }
            else
            {
                module_sp->GetFileSpec().GetPath (path, sizeof(path));
                sb_error.SetErrorStringWithFormat ("no object file for module '%s'", path);
            }
        }
        else
        {
            sb_error.SetErrorStringWithFormat ("invalid module");
        }
    }
    else
    {
        sb_error.SetErrorStringWithFormat ("invalid target");
    }
    return sb_error;
}


lldb::SBSymbolContextList
SBTarget::FindSymbols (const char *name, lldb::SymbolType symbol_type)
{
    SBSymbolContextList sb_sc_list;
    if (name && name[0])
    {
        TargetSP target_sp(GetSP());
        if (target_sp)
        {
            bool append = true;
            target_sp->GetImages().FindSymbolsWithNameAndType (ConstString(name),
                                                               symbol_type,
                                                               *sb_sc_list,
                                                               append);
        }
    }
    return sb_sc_list;
    
}


lldb::SBValue
SBTarget::EvaluateExpression (const char *expr, const SBExpressionOptions &options)
{
    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    Log * expr_log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
    SBValue expr_result;
    ExecutionResults exe_results = eExecutionSetupError;
    ValueObjectSP expr_value_sp;
    TargetSP target_sp(GetSP());
    StackFrame *frame = NULL;
    if (target_sp)
    {
        if (expr == NULL || expr[0] == '\0')
        {
            if (log)
                log->Printf ("SBTarget::EvaluateExpression called with an empty expression");
            return expr_result;
        }
        
        Mutex::Locker api_locker (target_sp->GetAPIMutex());
        ExecutionContext exe_ctx (m_opaque_sp.get());
        
        if (log)
            log->Printf ("SBTarget()::EvaluateExpression (expr=\"%s\")...", expr);
        
        frame = exe_ctx.GetFramePtr();
        Target *target = exe_ctx.GetTargetPtr();
        
        if (target)
        {
#ifdef LLDB_CONFIGURATION_DEBUG
            StreamString frame_description;
            if (frame)
                frame->DumpUsingSettingsFormat (&frame_description);
            Host::SetCrashDescriptionWithFormat ("SBTarget::EvaluateExpression (expr = \"%s\", fetch_dynamic_value = %u) %s",
                                                 expr, options.GetFetchDynamicValue(), frame_description.GetString().c_str());
#endif
            exe_results = target->EvaluateExpression (expr,
                                                      frame,
                                                      expr_value_sp,
                                                      options.ref());

            expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue());
#ifdef LLDB_CONFIGURATION_DEBUG
            Host::SetCrashDescription (NULL);
#endif
        }
        else
        {
            if (log)
                log->Printf ("SBTarget::EvaluateExpression () => error: could not reconstruct frame object for this SBTarget.");
        }
    }
#ifndef LLDB_DISABLE_PYTHON
    if (expr_log)
        expr_log->Printf("** [SBTarget::EvaluateExpression] Expression result is %s, summary %s **",
                         expr_result.GetValue(),
                         expr_result.GetSummary());
    
    if (log)
        log->Printf ("SBTarget(%p)::EvaluateExpression (expr=\"%s\") => SBValue(%p) (execution result=%d)",
                     frame,
                     expr,
                     expr_value_sp.get(),
                     exe_results);
#endif
    
    return expr_result;
}


lldb::addr_t
SBTarget::GetStackRedZoneSize()
{
    TargetSP target_sp(GetSP());
    if (target_sp)
    {
        ABISP abi_sp;
        ProcessSP process_sp (target_sp->GetProcessSP());
        if (process_sp)
            abi_sp = process_sp->GetABI();
        else
            abi_sp = ABI::FindPlugin(target_sp->GetArchitecture());
        if (abi_sp)
            return abi_sp->GetRedZoneSize();
    }
    return 0;
}

