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

#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/State.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.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/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)
    {
        Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
        if (process_sp->GetState() == eStateConnected)
        {
            if (stop_at_entry)
                launch_flags |= eLaunchFlagStopAtEntry;
            ProcessLaunchInfo launch_info (stdin_path,
                                           stdout_path,
                                           stderr_path,
                                           working_directory,
                                           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)
    {
        Mutex::Locker api_locker (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());
        Mutex::Locker api_locker (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)
    {
        Mutex::Locker api_locker (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)
    {
        Mutex::Locker api_locker (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)::GetProfileData (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)
    {
        Mutex::Locker api_locker (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)
    {
        Mutex::Locker api_locker (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)
    {
        Mutex::Locker api_locker (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());
        Mutex::Locker api_locker (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;

        Mutex::Locker api_locker (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;
        Mutex::Locker api_locker (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)
    {
        Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
        if (include_expression_stops)
            return process_sp->GetStopID();
        else
            return process_sp->GetLastNaturalStopID();
    }
    return 0;
}

StateType
SBProcess::GetState ()
{

    StateType ret_val = eStateInvalid;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Mutex::Locker api_locker (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)
    {
        Mutex::Locker api_locker (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)
    {
        Mutex::Locker api_locker (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)
    {
        Mutex::Locker api_locker (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)
    {
        Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
        sb_error.SetError(process_sp->Destroy());
    }
    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)
    {
        Mutex::Locker api_locker (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)
    {
        Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
        sb_error.SetError (process_sp->Destroy());
    }
    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)
    {
        Mutex::Locker api_locker (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)
    {
        Mutex::Locker api_locker (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()
{
    SBUnixSignals sb_unix_signals;
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        sb_unix_signals.SetSP(process_sp);
    }

    return sb_unix_signals;
}

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)
    {
        Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
        Process::StopLocker stop_locker;
        const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
        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)
    {
        Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
        Process::StopLocker stop_locker;
        const bool can_update = stop_locker.TryLock(&process_sp->GetRunLock());
        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)
{
    return Process::ProcessEventData::GetRestartedFromEvent (event.get());
}

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::EventIsProcessEvent (const SBEvent &event)
{
    return strcmp (event.GetBroadcasterClass(), SBProcess::GetBroadcasterClass()) == 0;
}

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()))
        {
            Mutex::Locker api_locker (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()))
        {
            Mutex::Locker api_locker (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()))
        {
            Mutex::Locker api_locker (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()))
        {
            Mutex::Locker api_locker (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()))
        {
            Mutex::Locker api_locker (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)
    {
        Mutex::Locker api_locker (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_image_spec, lldb::SBError &sb_error)
{
    ProcessSP process_sp(GetSP());
    if (process_sp)
    {
        Process::StopLocker stop_locker;
        if (stop_locker.TryLock(&process_sp->GetRunLock()))
        {
            Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
            return process_sp->LoadImage (*sb_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()))
        {
            Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex());
            sb_error.SetError (process_sp->UnloadImage (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()))
        {
            Mutex::Locker api_locker (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();
}
