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

// C Includes
#include <inttypes.h>

#include "lldb/lldb-defines.h"
#include "lldb/lldb-types.h"

#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Target/MemoryRegionInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/SystemRuntime.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"

// Project includes

#include "lldb/API/SBBroadcaster.h"
#include "lldb/API/SBCommandReturnObject.h"
#include "lldb/API/SBDebugger.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBFileSpec.h"
#include "lldb/API/SBMemoryRegionInfo.h"
#include "lldb/API/SBMemoryRegionInfoList.h"
#include "lldb/API/SBThread.h"
#include "lldb/API/SBThreadCollection.h"
#include "lldb/API/SBStream.h"
#include "lldb/API/SBStringList.h"
#include "lldb/API/SBUnixSignals.h"

using namespace lldb;
using namespace lldb_private;


SBProcess::SBProcess () :
    m_opaque_wp()
{
}


//----------------------------------------------------------------------
// SBProcess constructor
//----------------------------------------------------------------------

SBProcess::SBProcess (const SBProcess& rhs) :
    m_opaque_wp (rhs.m_opaque_wp)
{
}


SBProcess::SBProcess (const lldb::ProcessSP &process_sp) :
    m_opaque_wp (process_sp)
{
}

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

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

const char *
SBProcess::GetBroadcasterClassName ()
{
    return Process::GetStaticBroadcasterClass().AsCString();
}

const char *
SBProcess::GetPluginName ()
{
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        return process_sp->GetPluginName().GetCString();
    }
    return "<Unknown>";
}

const char *
SBProcess::GetShortPluginName ()
{
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        return process_sp->GetPluginName().GetCString();
    }
    return "<Unknown>";
}


lldb::ProcessSP
SBProcess::GetSP() const
{
    return m_opaque_wp.lock();
}

void
SBProcess::SetSP (const ProcessSP &process_sp)
{
    m_opaque_wp = process_sp;
}

void
SBProcess::Clear ()
{
    m_opaque_wp.reset();
}


bool
SBProcess::IsValid() const
{
    ProcessSP process_sp(m_opaque_wp.lock());
    return ((bool) process_sp && process_sp->IsValid());
}

bool
SBProcess::RemoteLaunch (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,
                         bool stop_at_entry,
                         lldb::SBError& error)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBProcess(%p)::RemoteLaunch (argv=%p, envp=%p, stdin=%s, stdout=%s, stderr=%s, working-dir=%s, launch_flags=0x%x, stop_at_entry=%i, &error (%p))...",
                     static_cast<void*>(m_opaque_wp.lock().get()),
                     static_cast<void*>(argv), static_cast<void*>(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,
                     static_cast<void*>(error.get()));

    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        if (process_sp->GetState() == eStateConnected)
        {
            if (stop_at_entry)
                launch_flags |= eLaunchFlagStopAtEntry;
            ProcessLaunchInfo launch_info(FileSpec{stdin_path, false},
                                          FileSpec{stdout_path, false},
                                          FileSpec{stderr_path, false},
                                          FileSpec{working_directory, false},
                                          launch_flags);
            Module *exe_module = process_sp->GetTarget().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));
        }
        else
        {
            error.SetErrorString ("must be in eStateConnected to call RemoteLaunch");
        }
    }
    else
    {
        error.SetErrorString ("unable to attach pid");
    }

    if (log) {
        SBStream sstr;
        error.GetDescription (sstr);
        log->Printf ("SBProcess(%p)::RemoteLaunch (...) => SBError (%p): %s",
                     static_cast<void*>(process_sp.get()),
                     static_cast<void*>(error.get()), sstr.GetData());
    }

    return error.Success();
}

bool
SBProcess::RemoteAttachToProcessWithID (lldb::pid_t pid, lldb::SBError& error)
{
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        if (process_sp->GetState() == eStateConnected)
        {
            ProcessAttachInfo attach_info;
            attach_info.SetProcessID (pid);
            error.SetError (process_sp->Attach (attach_info));
        }
        else
        {
            error.SetErrorString ("must be in eStateConnected to call RemoteAttachToProcessWithID");
        }
    }
    else
    {
        error.SetErrorString ("unable to attach pid");
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log) {
        SBStream sstr;
        error.GetDescription (sstr);
        log->Printf ("SBProcess(%p)::RemoteAttachToProcessWithID (%" PRIu64 ") => SBError (%p): %s",
                     static_cast<void*>(process_sp.get()), pid,
                     static_cast<void*>(error.get()), sstr.GetData());
    }

    return error.Success();
}


uint32_t
SBProcess::GetNumThreads ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    uint32_t num_threads = 0;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Process::StopLocker stop_locker;

        const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        num_threads = process_sp->GetThreadList().GetSize(can_update);
    }

    if (log)
        log->Printf ("SBProcess(%p)::GetNumThreads () => %d",
                     static_cast<void*>(process_sp.get()), num_threads);

    return num_threads;
}

SBThread
SBProcess::GetSelectedThread () const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBThread sb_thread;
    ThreadSP thread_sp;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        thread_sp = process_sp->GetThreadList().GetSelectedThread();
        sb_thread.SetThread (thread_sp);
    }

    if (log)
        log->Printf ("SBProcess(%p)::GetSelectedThread () => SBThread(%p)",
                     static_cast<void*>(process_sp.get()),
                     static_cast<void*>(thread_sp.get()));

    return sb_thread;
}

SBThread
SBProcess::CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBThread sb_thread;
    ThreadSP thread_sp;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        thread_sp = process_sp->CreateOSPluginThread(tid, context);
        sb_thread.SetThread (thread_sp);
    }

    if (log)
        log->Printf ("SBProcess(%p)::CreateOSPluginThread (tid=0x%" PRIx64 ", context=0x%" PRIx64 ") => SBThread(%p)",
                     static_cast<void*>(process_sp.get()), tid, context,
                     static_cast<void*>(thread_sp.get()));

    return sb_thread;
}

SBTarget
SBProcess::GetTarget() const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBTarget sb_target;
    TargetSP target_sp;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        target_sp = process_sp->GetTarget().shared_from_this();
        sb_target.SetSP (target_sp);
    }

    if (log)
        log->Printf ("SBProcess(%p)::GetTarget () => SBTarget(%p)",
                     static_cast<void*>(process_sp.get()),
                     static_cast<void*>(target_sp.get()));

    return sb_target;
}


size_t
SBProcess::PutSTDIN (const char *src, size_t src_len)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    size_t ret_val = 0;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Error error;
        ret_val =  process_sp->PutSTDIN (src, src_len, error);
    }

    if (log)
        log->Printf("SBProcess(%p)::PutSTDIN (src=\"%s\", src_len=%" PRIu64 ") => %" PRIu64,
                     static_cast<void*>(process_sp.get()), src,
                     static_cast<uint64_t>(src_len),
                     static_cast<uint64_t>(ret_val));

    return ret_val;
}

size_t
SBProcess::GetSTDOUT (char *dst, size_t dst_len) const
{
    size_t bytes_read = 0;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Error error;
        bytes_read = process_sp->GetSTDOUT (dst, dst_len, error);
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBProcess(%p)::GetSTDOUT (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64,
                     static_cast<void*>(process_sp.get()),
                     static_cast<int>(bytes_read), dst,
                     static_cast<uint64_t>(dst_len),
                     static_cast<uint64_t>(bytes_read));

    return bytes_read;
}

size_t
SBProcess::GetSTDERR (char *dst, size_t dst_len) const
{
    size_t bytes_read = 0;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Error error;
        bytes_read = process_sp->GetSTDERR (dst, dst_len, error);
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBProcess(%p)::GetSTDERR (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64,
                     static_cast<void*>(process_sp.get()),
                     static_cast<int>(bytes_read), dst,
                     static_cast<uint64_t>(dst_len),
                     static_cast<uint64_t>(bytes_read));

    return bytes_read;
}

size_t
SBProcess::GetAsyncProfileData(char *dst, size_t dst_len) const
{
    size_t bytes_read = 0;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Error error;
        bytes_read = process_sp->GetAsyncProfileData (dst, dst_len, error);
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBProcess(%p)::GetAsyncProfileData (dst=\"%.*s\", dst_len=%" PRIu64 ") => %" PRIu64,
                     static_cast<void*>(process_sp.get()),
                     static_cast<int>(bytes_read), dst,
                     static_cast<uint64_t>(dst_len),
                     static_cast<uint64_t>(bytes_read));

    return bytes_read;
}

void
SBProcess::ReportEventState (const SBEvent &event, FILE *out) const
{
    if (out == NULL)
        return;

    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        const StateType event_state = SBProcess::GetStateFromEvent (event);
        char message[1024];
        int message_len = ::snprintf (message,
                                      sizeof (message),
                                      "Process %" PRIu64 " %s\n",
                                      process_sp->GetID(),
                                      SBDebugger::StateAsCString (event_state));

        if (message_len > 0)
            ::fwrite (message, 1, message_len, out);
    }
}

void
SBProcess::AppendEventStateReport (const SBEvent &event, SBCommandReturnObject &result)
{
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        const StateType event_state = SBProcess::GetStateFromEvent (event);
        char message[1024];
        ::snprintf (message,
                    sizeof (message),
                    "Process %" PRIu64 " %s\n",
                    process_sp->GetID(),
                    SBDebugger::StateAsCString (event_state));

        result.AppendMessage (message);
    }
}

bool
SBProcess::SetSelectedThread (const SBThread &thread)
{
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        return process_sp->GetThreadList().SetSelectedThreadByID (thread.GetThreadID());
    }
    return false;
}

bool
SBProcess::SetSelectedThreadByID (lldb::tid_t tid)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    bool ret_val = false;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        ret_val = process_sp->GetThreadList().SetSelectedThreadByID (tid);
    }

    if (log)
        log->Printf ("SBProcess(%p)::SetSelectedThreadByID (tid=0x%4.4" PRIx64 ") => %s",
                     static_cast<void*>(process_sp.get()), tid,
                     (ret_val ? "true" : "false"));

    return ret_val;
}

bool
SBProcess::SetSelectedThreadByIndexID (uint32_t index_id)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    bool ret_val = false;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        ret_val = process_sp->GetThreadList().SetSelectedThreadByIndexID (index_id);
    }

    if (log)
        log->Printf ("SBProcess(%p)::SetSelectedThreadByID (tid=0x%x) => %s",
                     static_cast<void*>(process_sp.get()), index_id,
                     (ret_val ? "true" : "false"));

    return ret_val;
}

SBThread
SBProcess::GetThreadAtIndex (size_t index)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBThread sb_thread;
    ThreadSP thread_sp;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Process::StopLocker stop_locker;
        const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        thread_sp = process_sp->GetThreadList().GetThreadAtIndex(index, can_update);
        sb_thread.SetThread (thread_sp);
    }

    if (log)
        log->Printf ("SBProcess(%p)::GetThreadAtIndex (index=%d) => SBThread(%p)",
                     static_cast<void*>(process_sp.get()),
                     static_cast<uint32_t>(index),
                     static_cast<void*>(thread_sp.get()));

    return sb_thread;
}

uint32_t
SBProcess::GetNumQueues ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    uint32_t num_queues = 0;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process_sp->GetRunLock()))
        {
            std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
            num_queues = process_sp->GetQueueList().GetSize();
        }
    }

    if (log)
        log->Printf ("SBProcess(%p)::GetNumQueues () => %d",
                     static_cast<void*>(process_sp.get()), num_queues);

    return num_queues;
}

SBQueue
SBProcess::GetQueueAtIndex (size_t index)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBQueue sb_queue;
    QueueSP queue_sp;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process_sp->GetRunLock()))
        {
            std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
            queue_sp = process_sp->GetQueueList().GetQueueAtIndex(index);
            sb_queue.SetQueue (queue_sp);
        }
    }

    if (log)
        log->Printf ("SBProcess(%p)::GetQueueAtIndex (index=%d) => SBQueue(%p)",
                     static_cast<void*>(process_sp.get()),
                     static_cast<uint32_t>(index),
                     static_cast<void*>(queue_sp.get()));

    return sb_queue;
}


uint32_t
SBProcess::GetStopID(bool include_expression_stops)
{
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        if (include_expression_stops)
            return process_sp->GetStopID();
        else
            return process_sp->GetLastNaturalStopID();
    }
    return 0;
}

SBEvent
SBProcess::GetStopEventForStopID(uint32_t stop_id)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBEvent sb_event;
    EventSP event_sp;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        event_sp = process_sp->GetStopEventForStopID(stop_id);
        sb_event.reset(event_sp);
    }

    if (log)
        log->Printf ("SBProcess(%p)::GetStopEventForStopID (stop_id=%" PRIu32 ") => SBEvent(%p)",
                     static_cast<void*>(process_sp.get()),
                     stop_id,
                     static_cast<void*>(event_sp.get()));

    return sb_event;
}

StateType
SBProcess::GetState ()
{

    StateType ret_val = eStateInvalid;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        ret_val = process_sp->GetState();
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBProcess(%p)::GetState () => %s",
                     static_cast<void*>(process_sp.get()),
                     lldb_private::StateAsCString (ret_val));

    return ret_val;
}


int
SBProcess::GetExitStatus ()
{
    int exit_status = 0;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        exit_status = process_sp->GetExitStatus ();
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBProcess(%p)::GetExitStatus () => %i (0x%8.8x)",
                     static_cast<void*>(process_sp.get()), exit_status,
                     exit_status);

    return exit_status;
}

const char *
SBProcess::GetExitDescription ()
{
    const char *exit_desc = NULL;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        exit_desc = process_sp->GetExitDescription ();
    }
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBProcess(%p)::GetExitDescription () => %s",
                     static_cast<void*>(process_sp.get()), exit_desc);
    return exit_desc;
}

lldb::pid_t
SBProcess::GetProcessID ()
{
    lldb::pid_t ret_val = LLDB_INVALID_PROCESS_ID;
    ProcessSP process_sp(GetSP());
    if (process_sp)
        ret_val = process_sp->GetID();

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBProcess(%p)::GetProcessID () => %" PRIu64,
                     static_cast<void*>(process_sp.get()), ret_val);

    return ret_val;
}

uint32_t
SBProcess::GetUniqueID()
{
    uint32_t ret_val = 0;
    ProcessSP process_sp(GetSP());
    if (process_sp)
        ret_val = process_sp->GetUniqueID();
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBProcess(%p)::GetUniqueID () => %" PRIu32,
                     static_cast<void*>(process_sp.get()), ret_val);
    return ret_val;
}

ByteOrder
SBProcess::GetByteOrder () const
{
    ByteOrder byteOrder = eByteOrderInvalid;
    ProcessSP process_sp(GetSP());
    if (process_sp)
        byteOrder = process_sp->GetTarget().GetArchitecture().GetByteOrder();

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBProcess(%p)::GetByteOrder () => %d",
                     static_cast<void*>(process_sp.get()), byteOrder);

    return byteOrder;
}

uint32_t
SBProcess::GetAddressByteSize () const
{
    uint32_t size = 0;
    ProcessSP process_sp(GetSP());
    if (process_sp)
        size =  process_sp->GetTarget().GetArchitecture().GetAddressByteSize();

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBProcess(%p)::GetAddressByteSize () => %d",
                     static_cast<void*>(process_sp.get()), size);

    return size;
}

SBError
SBProcess::Continue ()
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    SBError sb_error;
    ProcessSP process_sp(GetSP());

    if (log)
        log->Printf ("SBProcess(%p)::Continue ()...",
                     static_cast<void*>(process_sp.get()));

    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());

        if (process_sp->GetTarget().GetDebugger().GetAsyncExecution ())
            sb_error.ref() = process_sp->Resume ();
        else
            sb_error.ref() = process_sp->ResumeSynchronous (NULL);
    }
    else
        sb_error.SetErrorString ("SBProcess is invalid");

    if (log)
    {
        SBStream sstr;
        sb_error.GetDescription (sstr);
        log->Printf ("SBProcess(%p)::Continue () => SBError (%p): %s",
                     static_cast<void*>(process_sp.get()),
                     static_cast<void*>(sb_error.get()), sstr.GetData());
    }

    return sb_error;
}


SBError
SBProcess::Destroy ()
{
    SBError sb_error;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        sb_error.SetError(process_sp->Destroy(false));
    }
    else
        sb_error.SetErrorString ("SBProcess is invalid");

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        SBStream sstr;
        sb_error.GetDescription (sstr);
        log->Printf ("SBProcess(%p)::Destroy () => SBError (%p): %s",
                     static_cast<void*>(process_sp.get()),
                     static_cast<void*>(sb_error.get()), sstr.GetData());
    }

    return sb_error;
}


SBError
SBProcess::Stop ()
{
    SBError sb_error;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        sb_error.SetError (process_sp->Halt());
    }
    else
        sb_error.SetErrorString ("SBProcess is invalid");

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        SBStream sstr;
        sb_error.GetDescription (sstr);
        log->Printf ("SBProcess(%p)::Stop () => SBError (%p): %s",
                     static_cast<void*>(process_sp.get()),
                     static_cast<void*>(sb_error.get()), sstr.GetData());
    }

    return sb_error;
}

SBError
SBProcess::Kill ()
{
    SBError sb_error;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        sb_error.SetError (process_sp->Destroy(true));
    }
    else
        sb_error.SetErrorString ("SBProcess is invalid");

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        SBStream sstr;
        sb_error.GetDescription (sstr);
        log->Printf ("SBProcess(%p)::Kill () => SBError (%p): %s",
                     static_cast<void*>(process_sp.get()),
                     static_cast<void*>(sb_error.get()), sstr.GetData());
    }

    return sb_error;
}

SBError
SBProcess::Detach ()
{
    // FIXME: This should come from a process default.
    bool keep_stopped = false;
    return Detach (keep_stopped);
}

SBError
SBProcess::Detach (bool keep_stopped)
{
    SBError sb_error;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        sb_error.SetError (process_sp->Detach(keep_stopped));
    }
    else
        sb_error.SetErrorString ("SBProcess is invalid");    

    return sb_error;
}

SBError
SBProcess::Signal (int signo)
{
    SBError sb_error;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        sb_error.SetError (process_sp->Signal (signo));
    }
    else
        sb_error.SetErrorString ("SBProcess is invalid");
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
    {
        SBStream sstr;
        sb_error.GetDescription (sstr);
        log->Printf ("SBProcess(%p)::Signal (signo=%i) => SBError (%p): %s",
                     static_cast<void*>(process_sp.get()), signo,
                     static_cast<void*>(sb_error.get()), sstr.GetData());
    }
    return sb_error;
}

SBUnixSignals
SBProcess::GetUnixSignals()
{
    if (auto process_sp = GetSP())
        return SBUnixSignals{process_sp};

    return {};
}

void
SBProcess::SendAsyncInterrupt ()
{
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        process_sp->SendAsyncInterrupt ();
    }
}

SBThread
SBProcess::GetThreadByID (tid_t tid)
{
    SBThread sb_thread;
    ThreadSP thread_sp;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Process::StopLocker stop_locker;
        const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        thread_sp = process_sp->GetThreadList().FindThreadByID (tid, can_update);
        sb_thread.SetThread (thread_sp);
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBProcess(%p)::GetThreadByID (tid=0x%4.4" PRIx64 ") => SBThread (%p)",
                     static_cast<void*>(process_sp.get()), tid,
                     static_cast<void*>(thread_sp.get()));

    return sb_thread;
}

SBThread
SBProcess::GetThreadByIndexID (uint32_t index_id)
{
    SBThread sb_thread;
    ThreadSP thread_sp;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Process::StopLocker stop_locker;
        const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        thread_sp = process_sp->GetThreadList().FindThreadByIndexID (index_id, can_update);
        sb_thread.SetThread (thread_sp);
    }

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
    if (log)
        log->Printf ("SBProcess(%p)::GetThreadByID (tid=0x%x) => SBThread (%p)",
                     static_cast<void*>(process_sp.get()), index_id,
                     static_cast<void*>(thread_sp.get()));

    return sb_thread;
}

StateType
SBProcess::GetStateFromEvent (const SBEvent &event)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    StateType ret_val = Process::ProcessEventData::GetStateFromEvent (event.get());

    if (log)
        log->Printf ("SBProcess::GetStateFromEvent (event.sp=%p) => %s",
                     static_cast<void*>(event.get()),
                     lldb_private::StateAsCString (ret_val));

    return ret_val;
}

bool
SBProcess::GetRestartedFromEvent (const SBEvent &event)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    bool ret_val = Process::ProcessEventData::GetRestartedFromEvent (event.get());

    if (log)
        log->Printf ("SBProcess::%s (event.sp=%p) => %d", __FUNCTION__,
                     static_cast<void*>(event.get()), ret_val);

    return ret_val;
}

size_t
SBProcess::GetNumRestartedReasonsFromEvent (const lldb::SBEvent &event)
{
    return Process::ProcessEventData::GetNumRestartedReasons(event.get());
}

const char *
SBProcess::GetRestartedReasonAtIndexFromEvent (const lldb::SBEvent &event, size_t idx)
{
    return Process::ProcessEventData::GetRestartedReasonAtIndex(event.get(), idx);
}

SBProcess
SBProcess::GetProcessFromEvent (const SBEvent &event)
{
    SBProcess process(Process::ProcessEventData::GetProcessFromEvent (event.get()));
    return process;
}

bool
SBProcess::GetInterruptedFromEvent (const SBEvent &event)
{
    return Process::ProcessEventData::GetInterruptedFromEvent(event.get());
}

bool
SBProcess::EventIsProcessEvent (const SBEvent &event)
{
    return event.GetBroadcasterClass() == SBProcess::GetBroadcasterClass();
}

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

    ProcessSP process_sp(GetSP());

    SBBroadcaster broadcaster(process_sp.get(), false);

    if (log)
        log->Printf ("SBProcess(%p)::GetBroadcaster () => SBBroadcaster (%p)",
                     static_cast<void*>(process_sp.get()),
                     static_cast<void*>(broadcaster.get()));

    return broadcaster;
}

const char *
SBProcess::GetBroadcasterClass ()
{
    return Process::GetStaticBroadcasterClass().AsCString();
}

size_t
SBProcess::ReadMemory (addr_t addr, void *dst, size_t dst_len, SBError &sb_error)
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    size_t bytes_read = 0;

    ProcessSP process_sp(GetSP());

    if (log)
        log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%" PRIx64 ", dst=%p, dst_len=%" PRIu64 ", SBError (%p))...",
                     static_cast<void*>(process_sp.get()), addr,
                     static_cast<void*>(dst), static_cast<uint64_t>(dst_len),
                     static_cast<void*>(sb_error.get()));

    if (process_sp)
    {
        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process_sp->GetRunLock()))
        {
            std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
            bytes_read = process_sp->ReadMemory (addr, dst, dst_len, sb_error.ref());
        }
        else
        {
            if (log)
                log->Printf ("SBProcess(%p)::ReadMemory() => error: process is running",
                             static_cast<void*>(process_sp.get()));
            sb_error.SetErrorString("process is running");
        }
    }
    else
    {
        sb_error.SetErrorString ("SBProcess is invalid");
    }

    if (log)
    {
        SBStream sstr;
        sb_error.GetDescription (sstr);
        log->Printf ("SBProcess(%p)::ReadMemory (addr=0x%" PRIx64 ", dst=%p, dst_len=%" PRIu64 ", SBError (%p): %s) => %" PRIu64,
                     static_cast<void*>(process_sp.get()), addr,
                     static_cast<void*>(dst), static_cast<uint64_t>(dst_len),
                     static_cast<void*>(sb_error.get()), sstr.GetData(),
                     static_cast<uint64_t>(bytes_read));
    }

    return bytes_read;
}

size_t
SBProcess::ReadCStringFromMemory (addr_t addr, void *buf, size_t size, lldb::SBError &sb_error)
{
    size_t bytes_read = 0;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process_sp->GetRunLock()))
        {
            std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
            bytes_read = process_sp->ReadCStringFromMemory (addr, (char *)buf, size, sb_error.ref());
        }
        else
        {
            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
            if (log)
                log->Printf ("SBProcess(%p)::ReadCStringFromMemory() => error: process is running",
                             static_cast<void*>(process_sp.get()));
            sb_error.SetErrorString("process is running");
        }
    }
    else
    {
        sb_error.SetErrorString ("SBProcess is invalid");
    }
    return bytes_read;
}

uint64_t
SBProcess::ReadUnsignedFromMemory (addr_t addr, uint32_t byte_size, lldb::SBError &sb_error)
{
    uint64_t value = 0;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process_sp->GetRunLock()))
        {
            std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
            value = process_sp->ReadUnsignedIntegerFromMemory (addr, byte_size, 0, sb_error.ref());
        }
        else
        {
            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
            if (log)
                log->Printf ("SBProcess(%p)::ReadUnsignedFromMemory() => error: process is running",
                             static_cast<void*>(process_sp.get()));
            sb_error.SetErrorString("process is running");
        }
    }
    else
    {
        sb_error.SetErrorString ("SBProcess is invalid");
    }
    return value;
}

lldb::addr_t
SBProcess::ReadPointerFromMemory (addr_t addr, lldb::SBError &sb_error)
{
    lldb::addr_t ptr = LLDB_INVALID_ADDRESS;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process_sp->GetRunLock()))
        {
            std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
            ptr = process_sp->ReadPointerFromMemory (addr, sb_error.ref());
        }
        else
        {
            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
            if (log)
                log->Printf ("SBProcess(%p)::ReadPointerFromMemory() => error: process is running",
                             static_cast<void*>(process_sp.get()));
            sb_error.SetErrorString("process is running");
        }
    }
    else
    {
        sb_error.SetErrorString ("SBProcess is invalid");
    }
    return ptr;
}

size_t
SBProcess::WriteMemory (addr_t addr, const void *src, size_t src_len, SBError &sb_error)
{
    size_t bytes_written = 0;

    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    ProcessSP process_sp(GetSP());

    if (log)
        log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%" PRIx64 ", src=%p, src_len=%" PRIu64 ", SBError (%p))...",
                     static_cast<void*>(process_sp.get()), addr,
                     static_cast<const void*>(src),
                     static_cast<uint64_t>(src_len),
                     static_cast<void*>(sb_error.get()));

    if (process_sp)
    {
        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process_sp->GetRunLock()))
        {
            std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
            bytes_written = process_sp->WriteMemory (addr, src, src_len, sb_error.ref());
        }
        else
        {
            if (log)
                log->Printf ("SBProcess(%p)::WriteMemory() => error: process is running",
                             static_cast<void*>(process_sp.get()));
            sb_error.SetErrorString("process is running");
        }
    }

    if (log)
    {
        SBStream sstr;
        sb_error.GetDescription (sstr);
        log->Printf ("SBProcess(%p)::WriteMemory (addr=0x%" PRIx64 ", src=%p, src_len=%" PRIu64 ", SBError (%p): %s) => %" PRIu64,
                     static_cast<void*>(process_sp.get()), addr,
                     static_cast<const void*>(src),
                     static_cast<uint64_t>(src_len),
                     static_cast<void*>(sb_error.get()), sstr.GetData(),
                     static_cast<uint64_t>(bytes_written));
    }

    return bytes_written;
}

bool
SBProcess::GetDescription (SBStream &description)
{
    Stream &strm = description.ref();

    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        char path[PATH_MAX];
        GetTarget().GetExecutable().GetPath (path, sizeof(path));
        Module *exe_module = process_sp->GetTarget().GetExecutableModulePointer();
        const char *exe_name = NULL;
        if (exe_module)
            exe_name = exe_module->GetFileSpec().GetFilename().AsCString();

        strm.Printf ("SBProcess: pid = %" PRIu64 ", state = %s, threads = %d%s%s",
                     process_sp->GetID(),
                     lldb_private::StateAsCString (GetState()), 
                     GetNumThreads(),
                     exe_name ? ", executable = " : "",
                     exe_name ? exe_name : "");
    }
    else
        strm.PutCString ("No value");

    return true;
}

uint32_t
SBProcess::GetNumSupportedHardwareWatchpoints (lldb::SBError &sb_error) const
{
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));

    uint32_t num = 0;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
        sb_error.SetError(process_sp->GetWatchpointSupportInfo (num));
        if (log)
            log->Printf ("SBProcess(%p)::GetNumSupportedHardwareWatchpoints () => %u",
                         static_cast<void*>(process_sp.get()), num);
    }
    else
    {
        sb_error.SetErrorString ("SBProcess is invalid");
    }
    return num;
}

uint32_t
SBProcess::LoadImage (lldb::SBFileSpec &sb_remote_image_spec, lldb::SBError &sb_error)
{
    return LoadImage(SBFileSpec(), sb_remote_image_spec, sb_error);
}

uint32_t
SBProcess::LoadImage (const lldb::SBFileSpec &sb_local_image_spec,
                      const lldb::SBFileSpec &sb_remote_image_spec,
                      lldb::SBError &sb_error)
{
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process_sp->GetRunLock()))
        {
            std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
            PlatformSP platform_sp = process_sp->GetTarget().GetPlatform();
            return platform_sp->LoadImage (process_sp.get(),
                                           *sb_local_image_spec,
                                           *sb_remote_image_spec,
                                           sb_error.ref());
        }
        else
        {
            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
            if (log)
                log->Printf ("SBProcess(%p)::LoadImage() => error: process is running",
                             static_cast<void*>(process_sp.get()));
            sb_error.SetErrorString("process is running");
        }
    }
    return LLDB_INVALID_IMAGE_TOKEN;
}

lldb::SBError
SBProcess::UnloadImage (uint32_t image_token)
{
    lldb::SBError sb_error;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process_sp->GetRunLock()))
        {
            std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
            PlatformSP platform_sp = process_sp->GetTarget().GetPlatform();
            sb_error.SetError (platform_sp->UnloadImage (process_sp.get(), image_token));
        }
        else
        {
            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
            if (log)
                log->Printf ("SBProcess(%p)::UnloadImage() => error: process is running",
                             static_cast<void*>(process_sp.get()));
            sb_error.SetErrorString("process is running");
        }
    }
    else
        sb_error.SetErrorString("invalid process");
    return sb_error;
}

lldb::SBError
SBProcess::SendEventData (const char *event_data)
{
    lldb::SBError sb_error;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process_sp->GetRunLock()))
        {
            std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
            sb_error.SetError (process_sp->SendEventData (event_data));
        }
        else
        {
            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
            if (log)
                log->Printf ("SBProcess(%p)::SendEventData() => error: process is running",
                             static_cast<void*>(process_sp.get()));
            sb_error.SetErrorString("process is running");
        }
    }
    else
        sb_error.SetErrorString("invalid process");
    return sb_error;
}

uint32_t
SBProcess::GetNumExtendedBacktraceTypes ()
{
    ProcessSP process_sp(GetSP());
    if (process_sp && process_sp->GetSystemRuntime())
    {
        SystemRuntime *runtime = process_sp->GetSystemRuntime();
        return runtime->GetExtendedBacktraceTypes().size();
    }
    return 0;
}

const char *
SBProcess::GetExtendedBacktraceTypeAtIndex (uint32_t idx)
{
    ProcessSP process_sp(GetSP());
    if (process_sp && process_sp->GetSystemRuntime())
    {
        SystemRuntime *runtime = process_sp->GetSystemRuntime();
        const std::vector<ConstString> &names = runtime->GetExtendedBacktraceTypes();
        if (idx < names.size())
        {
            return names[idx].AsCString();
        }
        else
        {
            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
            if (log)
                log->Printf("SBProcess(%p)::GetExtendedBacktraceTypeAtIndex() => error: requested extended backtrace name out of bounds",
                            static_cast<void*>(process_sp.get()));
        }
    }
    return NULL;
}

SBThreadCollection
SBProcess::GetHistoryThreads (addr_t addr)
{
    ProcessSP process_sp(GetSP());
    SBThreadCollection threads;
    if (process_sp)
    {
        threads = SBThreadCollection(process_sp->GetHistoryThreads(addr));
    }
    return threads;
}

bool
SBProcess::IsInstrumentationRuntimePresent(InstrumentationRuntimeType type)
{
    ProcessSP process_sp(GetSP());
    if (! process_sp)
        return false;
    
    InstrumentationRuntimeSP runtime_sp = process_sp->GetInstrumentationRuntime(type);
    
    if (! runtime_sp.get())
        return false;
    
    return runtime_sp->IsActive();
}

lldb::SBError
SBProcess::SaveCore(const char *file_name)
{
    lldb::SBError error;
    ProcessSP process_sp(GetSP());
    if (!process_sp)
    {
        error.SetErrorString("SBProcess is invalid");
        return error;
    }

    std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());

    if (process_sp->GetState() != eStateStopped)
    {
        error.SetErrorString("the process is not stopped");
        return error;
    }

    FileSpec core_file(file_name, false);
    error.ref() = PluginManager::SaveCore(process_sp, core_file);
    return error;
}

lldb::SBError
SBProcess::GetMemoryRegionInfo (lldb::addr_t load_addr, SBMemoryRegionInfo &sb_region_info)
{
    lldb::SBError sb_error;
    ProcessSP process_sp(GetSP());
    MemoryRegionInfoSP region_info_sp = std::make_shared<lldb_private::MemoryRegionInfo>();
    if (process_sp)
    {
        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process_sp->GetRunLock()))
        {
            std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
            sb_error.ref() = process_sp->GetMemoryRegionInfo(load_addr, *region_info_sp);
            if( sb_error.Success() ) {
                sb_region_info.ref() = *region_info_sp;
            }
        }
        else
        {
            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
            if (log)
                log->Printf ("SBProcess(%p)::GetMemoryRegionInfo() => error: process is running",
                             static_cast<void*>(process_sp.get()));
            sb_error.SetErrorString("process is running");
        }
    }
    else
    {
        sb_error.SetErrorString ("SBProcess is invalid");
    }
    return sb_error;
}

lldb::SBMemoryRegionInfoList
SBProcess::GetMemoryRegions()
{
    lldb::SBError sb_error;
    lldb::SBMemoryRegionInfoList sb_region_list;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process_sp->GetRunLock()))
        {
            std::lock_guard<std::recursive_mutex> guard(process_sp->GetTarget().GetAPIMutex());
            std::vector<MemoryRegionInfoSP> region_list;
            sb_error.ref() = process_sp->GetMemoryRegions(region_list);
            if( sb_error.Success() ) {
                std::vector<MemoryRegionInfoSP>::iterator end = region_list.end();
                for( std::vector<MemoryRegionInfoSP>::iterator it = region_list.begin(); it != end; it++ ) {
                    SBMemoryRegionInfo sb_region_info(it->get());
                    sb_region_list.Append(sb_region_info);
                }
            }
        }
        else
        {
            Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
            if (log)
                log->Printf ("SBProcess(%p)::GetMemoryRegionInfo() => error: process is running",
                             static_cast<void*>(process_sp.get()));
            sb_error.SetErrorString("process is running");
        }
    }
    else
    {
        sb_error.SetErrorString ("SBProcess is invalid");
    }
    return sb_region_list;
}
