//===-- ProcessMonitor.cpp ------------------------------------ -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// C Includes
#include <errno.h>
#include <poll.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ptrace.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>

// C++ Includes
// Other libraries and framework includes
#include "lldb/Core/Error.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/ThreadLauncher.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/UnixSignals.h"
#include "lldb/Utility/PseudoTerminal.h"

#include "Plugins/Process/POSIX/CrashReason.h"
#include "POSIXThread.h"
#include "ProcessFreeBSD.h"
#include "ProcessPOSIXLog.h"
#include "ProcessMonitor.h"

extern "C" {
      extern char ** environ;
 }

using namespace lldb;
using namespace lldb_private;

// We disable the tracing of ptrace calls for integration builds to
// avoid the additional indirection and checks.
#ifndef LLDB_CONFIGURATION_BUILDANDINTEGRATION
// Wrapper for ptrace to catch errors and log calls.

const char *
Get_PT_IO_OP(int op)
{
    switch (op) {
        case PIOD_READ_D:  return "READ_D";
        case PIOD_WRITE_D: return "WRITE_D";
        case PIOD_READ_I:  return "READ_I";
        case PIOD_WRITE_I: return "WRITE_I";
        default:           return "Unknown op";
    }
}

// Wrapper for ptrace to catch errors and log calls.
// Note that ptrace sets errno on error because -1 is reserved as a valid result.
extern long
PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
              const char* reqName, const char* file, int line)
{
    long int result;

    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));

    if (log) {
        log->Printf("ptrace(%s, %" PRIu64 ", %p, %x) called from file %s line %d",
                    reqName, pid, addr, data, file, line);
        if (req == PT_IO) {
            struct ptrace_io_desc *pi = (struct ptrace_io_desc *) addr;
            
            log->Printf("PT_IO: op=%s offs=%zx size=%zu",
                     Get_PT_IO_OP(pi->piod_op), (size_t)pi->piod_offs, pi->piod_len);
        }
    }

    //PtraceDisplayBytes(req, data);

    errno = 0;
    result = ptrace(req, pid, (caddr_t) addr, data);

    //PtraceDisplayBytes(req, data);

    if (log && errno != 0)
    {
        const char* str;
        switch (errno)
        {
        case ESRCH:  str = "ESRCH"; break;
        case EINVAL: str = "EINVAL"; break;
        case EBUSY:  str = "EBUSY"; break;
        case EPERM:  str = "EPERM"; break;
        default:     str = "<unknown>";
        }
        log->Printf("ptrace() failed; errno=%d (%s)", errno, str);
    }

    if (log) {
#ifdef __amd64__
        if (req == PT_GETREGS) {
            struct reg *r = (struct reg *) addr;

            log->Printf("PT_GETREGS: rip=0x%lx rsp=0x%lx rbp=0x%lx rax=0x%lx",
                        r->r_rip, r->r_rsp, r->r_rbp, r->r_rax);
        }
        if (req == PT_GETDBREGS || req == PT_SETDBREGS) {
            struct dbreg *r = (struct dbreg *) addr;
            char setget = (req == PT_GETDBREGS) ? 'G' : 'S';

            for (int i = 0; i <= 7; i++)
                log->Printf("PT_%cETDBREGS: dr[%d]=0x%lx", setget, i, r->dr[i]);
        }
#endif
    }
     
    return result;
}

// Wrapper for ptrace when logging is not required.
// Sets errno to 0 prior to calling ptrace.
extern long
PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data)
{
    long result = 0;
    errno = 0;
    result = ptrace(req, pid, (caddr_t)addr, data);
    return result;
}

#define PTRACE(req, pid, addr, data) \
    PtraceWrapper((req), (pid), (addr), (data), #req, __FILE__, __LINE__)
#else
    PtraceWrapper((req), (pid), (addr), (data))
#endif

//------------------------------------------------------------------------------
// Static implementations of ProcessMonitor::ReadMemory and
// ProcessMonitor::WriteMemory.  This enables mutual recursion between these
// functions without needed to go thru the thread funnel.

static size_t
DoReadMemory(lldb::pid_t pid, lldb::addr_t vm_addr, void *buf, size_t size, 
             Error &error)
{
    struct ptrace_io_desc pi_desc;

    pi_desc.piod_op = PIOD_READ_D;
    pi_desc.piod_offs = (void *)vm_addr;
    pi_desc.piod_addr = buf;
    pi_desc.piod_len = size;

    if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0)
        error.SetErrorToErrno();
    return pi_desc.piod_len;
}

static size_t
DoWriteMemory(lldb::pid_t pid, lldb::addr_t vm_addr, const void *buf, 
              size_t size, Error &error)
{
    struct ptrace_io_desc pi_desc;

    pi_desc.piod_op = PIOD_WRITE_D;
    pi_desc.piod_offs = (void *)vm_addr;
    pi_desc.piod_addr = (void *)buf;
    pi_desc.piod_len = size;

    if (PTRACE(PT_IO, pid, (caddr_t)&pi_desc, 0) < 0)
        error.SetErrorToErrno();
    return pi_desc.piod_len;
}

// Simple helper function to ensure flags are enabled on the given file
// descriptor.
static bool
EnsureFDFlags(int fd, int flags, Error &error)
{
    int status;

    if ((status = fcntl(fd, F_GETFL)) == -1)
    {
        error.SetErrorToErrno();
        return false;
    }

    if (fcntl(fd, F_SETFL, status | flags) == -1)
    {
        error.SetErrorToErrno();
        return false;
    }

    return true;
}

//------------------------------------------------------------------------------
/// @class Operation
/// @brief Represents a ProcessMonitor operation.
///
/// Under FreeBSD, it is not possible to ptrace() from any other thread but the
/// one that spawned or attached to the process from the start.  Therefore, when
/// a ProcessMonitor is asked to deliver or change the state of an inferior
/// process the operation must be "funneled" to a specific thread to perform the
/// task.  The Operation class provides an abstract base for all services the
/// ProcessMonitor must perform via the single virtual function Execute, thus
/// encapsulating the code that needs to run in the privileged context.
class Operation
{
public:
    virtual ~Operation() {}
    virtual void Execute(ProcessMonitor *monitor) = 0;
};

//------------------------------------------------------------------------------
/// @class ReadOperation
/// @brief Implements ProcessMonitor::ReadMemory.
class ReadOperation : public Operation
{
public:
    ReadOperation(lldb::addr_t addr, void *buff, size_t size,
                  Error &error, size_t &result)
        : m_addr(addr), m_buff(buff), m_size(size),
          m_error(error), m_result(result)
        { }

    void Execute(ProcessMonitor *monitor);

private:
    lldb::addr_t m_addr;
    void *m_buff;
    size_t m_size;
    Error &m_error;
    size_t &m_result;
};

void
ReadOperation::Execute(ProcessMonitor *monitor)
{
    lldb::pid_t pid = monitor->GetPID();

    m_result = DoReadMemory(pid, m_addr, m_buff, m_size, m_error);
}

//------------------------------------------------------------------------------
/// @class WriteOperation
/// @brief Implements ProcessMonitor::WriteMemory.
class WriteOperation : public Operation
{
public:
    WriteOperation(lldb::addr_t addr, const void *buff, size_t size,
                   Error &error, size_t &result)
        : m_addr(addr), m_buff(buff), m_size(size),
          m_error(error), m_result(result)
        { }

    void Execute(ProcessMonitor *monitor);

private:
    lldb::addr_t m_addr;
    const void *m_buff;
    size_t m_size;
    Error &m_error;
    size_t &m_result;
};

void
WriteOperation::Execute(ProcessMonitor *monitor)
{
    lldb::pid_t pid = monitor->GetPID();

    m_result = DoWriteMemory(pid, m_addr, m_buff, m_size, m_error);
}

//------------------------------------------------------------------------------
/// @class ReadRegOperation
/// @brief Implements ProcessMonitor::ReadRegisterValue.
class ReadRegOperation : public Operation
{
public:
    ReadRegOperation(lldb::tid_t tid, unsigned offset, unsigned size,
                     RegisterValue &value, bool &result)
        : m_tid(tid), m_offset(offset), m_size(size),
          m_value(value), m_result(result)
        { }

    void Execute(ProcessMonitor *monitor);

private:
    lldb::tid_t m_tid;
    unsigned m_offset;
    unsigned m_size;
    RegisterValue &m_value;
    bool &m_result;
};

void
ReadRegOperation::Execute(ProcessMonitor *monitor)
{
    struct reg regs;
    int rc;

    if ((rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)&regs, 0)) < 0) {
        m_result = false;
    } else {
        // 'struct reg' contains only 32- or 64-bit register values.  Punt on
        // others.  Also, not all entries may be uintptr_t sized, such as 32-bit
        // processes on powerpc64 (probably the same for i386 on amd64)
        if (m_size == sizeof(uint32_t))
            m_value = *(uint32_t *)(((caddr_t)&regs) + m_offset);
        else if (m_size == sizeof(uint64_t))
            m_value = *(uint64_t *)(((caddr_t)&regs) + m_offset);
        else
            memcpy(&m_value, (((caddr_t)&regs) + m_offset), m_size);
        m_result = true;
    }
}

//------------------------------------------------------------------------------
/// @class WriteRegOperation
/// @brief Implements ProcessMonitor::WriteRegisterValue.
class WriteRegOperation : public Operation
{
public:
    WriteRegOperation(lldb::tid_t tid, unsigned offset,
                      const RegisterValue &value, bool &result)
        : m_tid(tid), m_offset(offset),
          m_value(value), m_result(result)
        { }

    void Execute(ProcessMonitor *monitor);

private:
    lldb::tid_t m_tid;
    unsigned m_offset;
    const RegisterValue &m_value;
    bool &m_result;
};

void
WriteRegOperation::Execute(ProcessMonitor *monitor)
{
    struct reg regs;

    if (PTRACE(PT_GETREGS, m_tid, (caddr_t)&regs, 0) < 0) {
        m_result = false;
        return;
    }
    *(uintptr_t *)(((caddr_t)&regs) + m_offset) = (uintptr_t)m_value.GetAsUInt64();
    if (PTRACE(PT_SETREGS, m_tid, (caddr_t)&regs, 0) < 0)
        m_result = false;
    else
        m_result = true;
}

//------------------------------------------------------------------------------
/// @class ReadDebugRegOperation
/// @brief Implements ProcessMonitor::ReadDebugRegisterValue.
class ReadDebugRegOperation : public Operation
{
public:
    ReadDebugRegOperation(lldb::tid_t tid, unsigned offset, unsigned size,
                          RegisterValue &value, bool &result)
        : m_tid(tid), m_offset(offset), m_size(size),
          m_value(value), m_result(result)
        { }

    void Execute(ProcessMonitor *monitor);

private:
    lldb::tid_t m_tid;
    unsigned m_offset;
    unsigned m_size;
    RegisterValue &m_value;
    bool &m_result;
};

void
ReadDebugRegOperation::Execute(ProcessMonitor *monitor)
{
    struct dbreg regs;
    int rc;

    if ((rc = PTRACE(PT_GETDBREGS, m_tid, (caddr_t)&regs, 0)) < 0) {
        m_result = false;
    } else {
        if (m_size == sizeof(uintptr_t))
            m_value = *(uintptr_t *)(((caddr_t)&regs) + m_offset);
        else
            memcpy(&m_value, (((caddr_t)&regs) + m_offset), m_size);
        m_result = true;
    }
}

//------------------------------------------------------------------------------
/// @class WriteDebugRegOperation
/// @brief Implements ProcessMonitor::WriteDebugRegisterValue.
class WriteDebugRegOperation : public Operation
{
public:
    WriteDebugRegOperation(lldb::tid_t tid, unsigned offset,
                           const RegisterValue &value, bool &result)
        : m_tid(tid), m_offset(offset),
          m_value(value), m_result(result)
        { }

    void Execute(ProcessMonitor *monitor);

private:
    lldb::tid_t m_tid;
    unsigned m_offset;
    const RegisterValue &m_value;
    bool &m_result;
};

void
WriteDebugRegOperation::Execute(ProcessMonitor *monitor)
{
    struct dbreg regs;

    if (PTRACE(PT_GETDBREGS, m_tid, (caddr_t)&regs, 0) < 0) {
        m_result = false;
        return;
    }
    *(uintptr_t *)(((caddr_t)&regs) + m_offset) = (uintptr_t)m_value.GetAsUInt64();
    if (PTRACE(PT_SETDBREGS, m_tid, (caddr_t)&regs, 0) < 0)
        m_result = false;
    else
        m_result = true;
}

//------------------------------------------------------------------------------
/// @class ReadGPROperation
/// @brief Implements ProcessMonitor::ReadGPR.
class ReadGPROperation : public Operation
{
public:
    ReadGPROperation(lldb::tid_t tid, void *buf, bool &result)
        : m_tid(tid), m_buf(buf), m_result(result)
        { }

    void Execute(ProcessMonitor *monitor);

private:
    lldb::tid_t m_tid;
    void *m_buf;
    bool &m_result;
};

void
ReadGPROperation::Execute(ProcessMonitor *monitor)
{
    int rc;

    errno = 0;
    rc = PTRACE(PT_GETREGS, m_tid, (caddr_t)m_buf, 0);
    if (errno != 0)
        m_result = false;
    else
        m_result = true;
}

//------------------------------------------------------------------------------
/// @class ReadFPROperation
/// @brief Implements ProcessMonitor::ReadFPR.
class ReadFPROperation : public Operation
{
public:
    ReadFPROperation(lldb::tid_t tid, void *buf, bool &result)
        : m_tid(tid), m_buf(buf), m_result(result)
        { }

    void Execute(ProcessMonitor *monitor);

private:
    lldb::tid_t m_tid;
    void *m_buf;
    bool &m_result;
};

void
ReadFPROperation::Execute(ProcessMonitor *monitor)
{
    if (PTRACE(PT_GETFPREGS, m_tid, (caddr_t)m_buf, 0) < 0)
        m_result = false;
    else
        m_result = true;
}

//------------------------------------------------------------------------------
/// @class WriteGPROperation
/// @brief Implements ProcessMonitor::WriteGPR.
class WriteGPROperation : public Operation
{
public:
    WriteGPROperation(lldb::tid_t tid, void *buf, bool &result)
        : m_tid(tid), m_buf(buf), m_result(result)
        { }

    void Execute(ProcessMonitor *monitor);

private:
    lldb::tid_t m_tid;
    void *m_buf;
    bool &m_result;
};

void
WriteGPROperation::Execute(ProcessMonitor *monitor)
{
    if (PTRACE(PT_SETREGS, m_tid, (caddr_t)m_buf, 0) < 0)
        m_result = false;
    else
        m_result = true;
}

//------------------------------------------------------------------------------
/// @class WriteFPROperation
/// @brief Implements ProcessMonitor::WriteFPR.
class WriteFPROperation : public Operation
{
public:
    WriteFPROperation(lldb::tid_t tid, void *buf, bool &result)
        : m_tid(tid), m_buf(buf), m_result(result)
        { }

    void Execute(ProcessMonitor *monitor);

private:
    lldb::tid_t m_tid;
    void *m_buf;
    bool &m_result;
};

void
WriteFPROperation::Execute(ProcessMonitor *monitor)
{
    if (PTRACE(PT_SETFPREGS, m_tid, (caddr_t)m_buf, 0) < 0)
        m_result = false;
    else
        m_result = true;
}

//------------------------------------------------------------------------------
/// @class ResumeOperation
/// @brief Implements ProcessMonitor::Resume.
class ResumeOperation : public Operation
{
public:
    ResumeOperation(uint32_t signo, bool &result) :
        m_signo(signo), m_result(result) { }

    void Execute(ProcessMonitor *monitor);

private:
    uint32_t m_signo;
    bool &m_result;
};

void
ResumeOperation::Execute(ProcessMonitor *monitor)
{
    lldb::pid_t pid = monitor->GetPID();
    int data = 0;

    if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
        data = m_signo;

    if (PTRACE(PT_CONTINUE, pid, (caddr_t)1, data))
    {
        Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));

        if (log)
            log->Printf ("ResumeOperation (%"  PRIu64 ") failed: %s", pid, strerror(errno));
        m_result = false;
    }
    else
        m_result = true;
}

//------------------------------------------------------------------------------
/// @class SingleStepOperation
/// @brief Implements ProcessMonitor::SingleStep.
class SingleStepOperation : public Operation
{
public:
    SingleStepOperation(uint32_t signo, bool &result)
        : m_signo(signo), m_result(result) { }

    void Execute(ProcessMonitor *monitor);

private:
    uint32_t m_signo;
    bool &m_result;
};

void
SingleStepOperation::Execute(ProcessMonitor *monitor)
{
    lldb::pid_t pid = monitor->GetPID();
    int data = 0;

    if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
        data = m_signo;

    if (PTRACE(PT_STEP, pid, NULL, data))
        m_result = false;
    else
        m_result = true;
}

//------------------------------------------------------------------------------
/// @class LwpInfoOperation
/// @brief Implements ProcessMonitor::GetLwpInfo.
class LwpInfoOperation : public Operation
{
public:
    LwpInfoOperation(lldb::tid_t tid, void *info, bool &result, int &ptrace_err)
        : m_tid(tid), m_info(info), m_result(result), m_err(ptrace_err) { }

    void Execute(ProcessMonitor *monitor);

private:
    lldb::tid_t m_tid;
    void *m_info;
    bool &m_result;
    int &m_err;
};

void
LwpInfoOperation::Execute(ProcessMonitor *monitor)
{
    struct ptrace_lwpinfo plwp;

    if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp))) {
        m_result = false;
        m_err = errno;
    } else {
        memcpy(m_info, &plwp, sizeof(plwp));
        m_result = true;
    }
}

//------------------------------------------------------------------------------
/// @class ThreadSuspendOperation
/// @brief Implements ProcessMonitor::ThreadSuspend.
class ThreadSuspendOperation : public Operation
{
public:
    ThreadSuspendOperation(lldb::tid_t tid, bool suspend, bool &result)
        : m_tid(tid), m_suspend(suspend), m_result(result) { }

    void Execute(ProcessMonitor *monitor);

private:
    lldb::tid_t m_tid;
    bool m_suspend;
    bool &m_result;
} ;

void
ThreadSuspendOperation::Execute(ProcessMonitor *monitor)
{
    m_result = !PTRACE(m_suspend ? PT_SUSPEND : PT_RESUME, m_tid, NULL, 0);
}



//------------------------------------------------------------------------------
/// @class EventMessageOperation
/// @brief Implements ProcessMonitor::GetEventMessage.
class EventMessageOperation : public Operation
{
public:
    EventMessageOperation(lldb::tid_t tid, unsigned long *message, bool &result)
        : m_tid(tid), m_message(message), m_result(result) { }

    void Execute(ProcessMonitor *monitor);

private:
    lldb::tid_t m_tid;
    unsigned long *m_message;
    bool &m_result;
};

void
EventMessageOperation::Execute(ProcessMonitor *monitor)
{
    struct ptrace_lwpinfo plwp;

    if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp)))
        m_result = false;
    else {
        if (plwp.pl_flags & PL_FLAG_FORKED) {
            *m_message = plwp.pl_child_pid;
            m_result = true;
        } else
            m_result = false;
    }
}

//------------------------------------------------------------------------------
/// @class KillOperation
/// @brief Implements ProcessMonitor::Kill.
class KillOperation : public Operation
{
public:
    KillOperation(bool &result) : m_result(result) { }

    void Execute(ProcessMonitor *monitor);

private:
    bool &m_result;
};

void
KillOperation::Execute(ProcessMonitor *monitor)
{
    lldb::pid_t pid = monitor->GetPID();

    if (PTRACE(PT_KILL, pid, NULL, 0))
        m_result = false;
    else
        m_result = true;
}

//------------------------------------------------------------------------------
/// @class DetachOperation
/// @brief Implements ProcessMonitor::Detach.
class DetachOperation : public Operation
{
public:
    DetachOperation(Error &result) : m_error(result) { }

    void Execute(ProcessMonitor *monitor);

private:
    Error &m_error;
};

void
DetachOperation::Execute(ProcessMonitor *monitor)
{
    lldb::pid_t pid = monitor->GetPID();

    if (PTRACE(PT_DETACH, pid, NULL, 0) < 0)
        m_error.SetErrorToErrno();
  
}

ProcessMonitor::OperationArgs::OperationArgs(ProcessMonitor *monitor)
    : m_monitor(monitor)
{
    sem_init(&m_semaphore, 0, 0);
}

ProcessMonitor::OperationArgs::~OperationArgs()
{
    sem_destroy(&m_semaphore);
}

ProcessMonitor::LaunchArgs::LaunchArgs(ProcessMonitor *monitor,
                                       lldb_private::Module *module,
                                       char const **argv,
                                       char const **envp,
                                       const FileSpec &stdin_file_spec,
                                       const FileSpec &stdout_file_spec,
                                       const FileSpec &stderr_file_spec,
                                       const FileSpec &working_dir)
    : OperationArgs(monitor),
      m_module(module),
      m_argv(argv),
      m_envp(envp),
      m_stdin_file_spec(stdin_file_spec),
      m_stdout_file_spec(stdout_file_spec),
      m_stderr_file_spec(stderr_file_spec),
      m_working_dir(working_dir) { }

ProcessMonitor::LaunchArgs::~LaunchArgs()
{ }

ProcessMonitor::AttachArgs::AttachArgs(ProcessMonitor *monitor,
                                       lldb::pid_t pid)
    : OperationArgs(monitor), m_pid(pid) { }

ProcessMonitor::AttachArgs::~AttachArgs()
{ }

//------------------------------------------------------------------------------
/// The basic design of the ProcessMonitor is built around two threads.
///
/// One thread (@see SignalThread) simply blocks on a call to waitpid() looking
/// for changes in the debugee state.  When a change is detected a
/// ProcessMessage is sent to the associated ProcessFreeBSD instance.  This thread
/// "drives" state changes in the debugger.
///
/// The second thread (@see OperationThread) is responsible for two things 1)
/// launching or attaching to the inferior process, and then 2) servicing
/// operations such as register reads/writes, stepping, etc.  See the comments
/// on the Operation class for more info as to why this is needed.
ProcessMonitor::ProcessMonitor(ProcessPOSIX *process,
                               Module *module,
                               const char *argv[],
                               const char *envp[],
                               const FileSpec &stdin_file_spec,
                               const FileSpec &stdout_file_spec,
                               const FileSpec &stderr_file_spec,
                               const FileSpec &working_dir,
                               const lldb_private::ProcessLaunchInfo & /* launch_info */,
                               lldb_private::Error &error)
    : m_process(static_cast<ProcessFreeBSD *>(process)),
      m_pid(LLDB_INVALID_PROCESS_ID),
      m_terminal_fd(-1),
      m_operation(0)
{
    std::unique_ptr<LaunchArgs> args(new LaunchArgs(this, module, argv, envp,
                                                    stdin_file_spec,
                                                    stdout_file_spec,
                                                    stderr_file_spec,
                                                    working_dir));
    

    sem_init(&m_operation_pending, 0, 0);
    sem_init(&m_operation_done, 0, 0);

    StartLaunchOpThread(args.get(), error);
    if (!error.Success())
        return;

WAIT_AGAIN:
    // Wait for the operation thread to initialize.
    if (sem_wait(&args->m_semaphore))
    {
        if (errno == EINTR)
            goto WAIT_AGAIN;
        else
        {
            error.SetErrorToErrno();
            return;
        }
    }

    // Check that the launch was a success.
    if (!args->m_error.Success())
    {
        StopOpThread();
        error = args->m_error;
        return;
    }

    // Finally, start monitoring the child process for change in state.
    m_monitor_thread = Host::StartMonitoringChildProcess(
        ProcessMonitor::MonitorCallback, this, GetPID(), true);
    if (!m_monitor_thread.IsJoinable())
    {
        error.SetErrorToGenericError();
        error.SetErrorString("Process launch failed.");
        return;
    }
}

ProcessMonitor::ProcessMonitor(ProcessPOSIX *process,
                               lldb::pid_t pid,
                               lldb_private::Error &error)
    : m_process(static_cast<ProcessFreeBSD *>(process)),
      m_pid(pid),
      m_terminal_fd(-1),
      m_operation(0)
{
    sem_init(&m_operation_pending, 0, 0);
    sem_init(&m_operation_done, 0, 0);


    std::unique_ptr<AttachArgs> args(new AttachArgs(this, pid));

    StartAttachOpThread(args.get(), error);
    if (!error.Success())
        return;

WAIT_AGAIN:
    // Wait for the operation thread to initialize.
    if (sem_wait(&args->m_semaphore))
    {
        if (errno == EINTR)
            goto WAIT_AGAIN;
        else
        {
            error.SetErrorToErrno();
            return;
        }
    }

    // Check that the attach was a success.
    if (!args->m_error.Success())
    {
        StopOpThread();
        error = args->m_error;
        return;
    }

    // Finally, start monitoring the child process for change in state.
    m_monitor_thread = Host::StartMonitoringChildProcess(
        ProcessMonitor::MonitorCallback, this, GetPID(), true);
    if (!m_monitor_thread.IsJoinable())
    {
        error.SetErrorToGenericError();
        error.SetErrorString("Process attach failed.");
        return;
    }
}

ProcessMonitor::~ProcessMonitor()
{
    StopMonitor();
}

//------------------------------------------------------------------------------
// Thread setup and tear down.
void
ProcessMonitor::StartLaunchOpThread(LaunchArgs *args, Error &error)
{
    static const char *g_thread_name = "lldb.process.freebsd.operation";

    if (m_operation_thread.IsJoinable())
        return;

    m_operation_thread = ThreadLauncher::LaunchThread(g_thread_name, LaunchOpThread, args, &error);
}

void *
ProcessMonitor::LaunchOpThread(void *arg)
{
    LaunchArgs *args = static_cast<LaunchArgs*>(arg);

    if (!Launch(args)) {
        sem_post(&args->m_semaphore);
        return NULL;
    }

    ServeOperation(args);
    return NULL;
}

bool
ProcessMonitor::Launch(LaunchArgs *args)
{
    ProcessMonitor *monitor = args->m_monitor;
    ProcessFreeBSD &process = monitor->GetProcess();
    const char **argv = args->m_argv;
    const char **envp = args->m_envp;
    const FileSpec &stdin_file_spec = args->m_stdin_file_spec;
    const FileSpec &stdout_file_spec = args->m_stdout_file_spec;
    const FileSpec &stderr_file_spec = args->m_stderr_file_spec;
    const FileSpec &working_dir = args->m_working_dir;

    lldb_utility::PseudoTerminal terminal;
    const size_t err_len = 1024;
    char err_str[err_len];
    ::pid_t pid;

    // Propagate the environment if one is not supplied.
    if (envp == NULL || envp[0] == NULL)
        envp = const_cast<const char **>(environ);

    if ((pid = terminal.Fork(err_str, err_len)) == -1)
    {
        args->m_error.SetErrorToGenericError();
        args->m_error.SetErrorString("Process fork failed.");
        goto FINISH;
    }

    // Recognized child exit status codes.
    enum {
        ePtraceFailed = 1,
        eDupStdinFailed,
        eDupStdoutFailed,
        eDupStderrFailed,
        eChdirFailed,
        eExecFailed,
        eSetGidFailed
    };

    // Child process.
    if (pid == 0)
    {
        // Trace this process.
        if (PTRACE(PT_TRACE_ME, 0, NULL, 0) < 0)
            exit(ePtraceFailed);

        // terminal has already dupped the tty descriptors to stdin/out/err.
        // This closes original fd from which they were copied (and avoids
        // leaking descriptors to the debugged process.
        terminal.CloseSlaveFileDescriptor();

        // Do not inherit setgid powers.
        if (setgid(getgid()) != 0)
            exit(eSetGidFailed);

        // Let us have our own process group.
        setpgid(0, 0);

        // Dup file descriptors if needed.
        //
        // FIXME: If two or more of the paths are the same we needlessly open
        // the same file multiple times.
        if (stdin_file_spec)
            if (!DupDescriptor(stdin_file_spec, STDIN_FILENO, O_RDONLY))
                exit(eDupStdinFailed);

        if (stdout_file_spec)
            if (!DupDescriptor(stdout_file_spec, STDOUT_FILENO, O_WRONLY | O_CREAT))
                exit(eDupStdoutFailed);

        if (stderr_file_spec)
            if (!DupDescriptor(stderr_file_spec, STDERR_FILENO, O_WRONLY | O_CREAT))
                exit(eDupStderrFailed);

        // Change working directory
        if (working_dir && 0 != ::chdir(working_dir.GetCString()))
            exit(eChdirFailed);

        // Execute.  We should never return.
        execve(argv[0],
               const_cast<char *const *>(argv),
               const_cast<char *const *>(envp));
        exit(eExecFailed);
    }

    // Wait for the child process to to trap on its call to execve.
    ::pid_t wpid;
    int status;
    if ((wpid = waitpid(pid, &status, 0)) < 0)
    {
        args->m_error.SetErrorToErrno();
        goto FINISH;
    }
    else if (WIFEXITED(status))
    {
        // open, dup or execve likely failed for some reason.
        args->m_error.SetErrorToGenericError();
        switch (WEXITSTATUS(status))
        {
            case ePtraceFailed:
                args->m_error.SetErrorString("Child ptrace failed.");
                break;
            case eDupStdinFailed:
                args->m_error.SetErrorString("Child open stdin failed.");
                break;
            case eDupStdoutFailed:
                args->m_error.SetErrorString("Child open stdout failed.");
                break;
            case eDupStderrFailed:
                args->m_error.SetErrorString("Child open stderr failed.");
                break;
            case eChdirFailed:
                args->m_error.SetErrorString("Child failed to set working directory.");
                break;
            case eExecFailed:
                args->m_error.SetErrorString("Child exec failed.");
                break;
            case eSetGidFailed:
                args->m_error.SetErrorString("Child setgid failed.");
                break;
            default:
                args->m_error.SetErrorString("Child returned unknown exit status.");
                break;
        }
        goto FINISH;
    }
    assert(WIFSTOPPED(status) && wpid == (::pid_t)pid &&
           "Could not sync with inferior process.");

#ifdef notyet
    // Have the child raise an event on exit.  This is used to keep the child in
    // limbo until it is destroyed.
    if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_TRACEEXIT) < 0)
    {
        args->m_error.SetErrorToErrno();
        goto FINISH;
    }
#endif
    // Release the master terminal descriptor and pass it off to the
    // ProcessMonitor instance.  Similarly stash the inferior pid.
    monitor->m_terminal_fd = terminal.ReleaseMasterFileDescriptor();
    monitor->m_pid = pid;

    // Set the terminal fd to be in non blocking mode (it simplifies the
    // implementation of ProcessFreeBSD::GetSTDOUT to have a non-blocking
    // descriptor to read from).
    if (!EnsureFDFlags(monitor->m_terminal_fd, O_NONBLOCK, args->m_error))
        goto FINISH;

    process.SendMessage(ProcessMessage::Attach(pid));

FINISH:
    return args->m_error.Success();
}

void
ProcessMonitor::StartAttachOpThread(AttachArgs *args, lldb_private::Error &error)
{
    static const char *g_thread_name = "lldb.process.freebsd.operation";

    if (m_operation_thread.IsJoinable())
        return;

    m_operation_thread = ThreadLauncher::LaunchThread(g_thread_name, AttachOpThread, args, &error);
}

void *
ProcessMonitor::AttachOpThread(void *arg)
{
    AttachArgs *args = static_cast<AttachArgs*>(arg);

    Attach(args);

    ServeOperation(args);
    return NULL;
}

void
ProcessMonitor::Attach(AttachArgs *args)
{
    lldb::pid_t pid = args->m_pid;

    ProcessMonitor *monitor = args->m_monitor;
    ProcessFreeBSD &process = monitor->GetProcess();

    if (pid <= 1)
    {
        args->m_error.SetErrorToGenericError();
        args->m_error.SetErrorString("Attaching to process 1 is not allowed.");
        return;
    }

    // Attach to the requested process.
    if (PTRACE(PT_ATTACH, pid, NULL, 0) < 0)
    {
        args->m_error.SetErrorToErrno();
        return;
    }

    int status;
    if ((status = waitpid(pid, NULL, 0)) < 0)
    {
        args->m_error.SetErrorToErrno();
        return;
    }

    process.SendMessage(ProcessMessage::Attach(pid));
}

size_t
ProcessMonitor::GetCurrentThreadIDs(std::vector<lldb::tid_t>&thread_ids)
{
    lwpid_t *tids;
    int tdcnt;

    thread_ids.clear();

    tdcnt = PTRACE(PT_GETNUMLWPS, m_pid, NULL, 0);
    if (tdcnt <= 0)
        return 0;
    tids = (lwpid_t *)malloc(tdcnt * sizeof(*tids));
    if (tids == NULL)
        return 0;
    if (PTRACE(PT_GETLWPLIST, m_pid, (void *)tids, tdcnt) < 0) {
        free(tids);
        return 0;
    }
    thread_ids = std::vector<lldb::tid_t>(tids, tids + tdcnt);
    free(tids);
    return thread_ids.size();
}

bool
ProcessMonitor::MonitorCallback(void *callback_baton,
                                lldb::pid_t pid,
                                bool exited,
                                int signal,
                                int status)
{
    ProcessMessage message;
    ProcessMonitor *monitor = static_cast<ProcessMonitor*>(callback_baton);
    ProcessFreeBSD *process = monitor->m_process;
    assert(process);
    bool stop_monitoring;
    struct ptrace_lwpinfo plwp;
    int ptrace_err;

    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));

    if (exited)
    {
        if (log)
            log->Printf ("ProcessMonitor::%s() got exit signal, tid = %"  PRIu64, __FUNCTION__, pid);
        message = ProcessMessage::Exit(pid, status);
        process->SendMessage(message);
        return pid == process->GetID();
    }

    if (!monitor->GetLwpInfo(pid, &plwp, ptrace_err))
        stop_monitoring = true; // pid is gone.  Bail.
    else {
        switch (plwp.pl_siginfo.si_signo)
        {
        case SIGTRAP:
            message = MonitorSIGTRAP(monitor, &plwp.pl_siginfo, plwp.pl_lwpid);
            break;
            
        default:
            message = MonitorSignal(monitor, &plwp.pl_siginfo, plwp.pl_lwpid);
            break;
        }

        process->SendMessage(message);
        stop_monitoring = message.GetKind() == ProcessMessage::eExitMessage;
    }

    return stop_monitoring;
}

ProcessMessage
ProcessMonitor::MonitorSIGTRAP(ProcessMonitor *monitor,
                               const siginfo_t *info, lldb::tid_t tid)
{
    ProcessMessage message;

    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));

    assert(monitor);
    assert(info && info->si_signo == SIGTRAP && "Unexpected child signal!");

    switch (info->si_code)
    {
    default:
        assert(false && "Unexpected SIGTRAP code!");
        break;

    case (SIGTRAP /* | (PTRACE_EVENT_EXIT << 8) */):
    {
        // The inferior process is about to exit.  Maintain the process in a
        // state of "limbo" until we are explicitly commanded to detach,
        // destroy, resume, etc.
        unsigned long data = 0;
        if (!monitor->GetEventMessage(tid, &data))
            data = -1;
        if (log)
            log->Printf ("ProcessMonitor::%s() received exit? event, data = %lx, tid = %" PRIu64, __FUNCTION__, data, tid);
        message = ProcessMessage::Limbo(tid, (data >> 8));
        break;
    }

    case 0:
    case TRAP_TRACE:
        if (log)
            log->Printf ("ProcessMonitor::%s() received trace event, tid = %" PRIu64 "  : si_code = %d", __FUNCTION__, tid, info->si_code);
        message = ProcessMessage::Trace(tid);
        break;

    case SI_KERNEL:
    case TRAP_BRKPT:
        if (log)
            log->Printf ("ProcessMonitor::%s() received breakpoint event, tid = %" PRIu64, __FUNCTION__, tid);
        message = ProcessMessage::Break(tid);
        break;
    }

    return message;
}

ProcessMessage
ProcessMonitor::MonitorSignal(ProcessMonitor *monitor,
                              const siginfo_t *info, lldb::tid_t tid)
{
    ProcessMessage message;
    int signo = info->si_signo;

    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));

    // POSIX says that process behaviour is undefined after it ignores a SIGFPE,
    // SIGILL, SIGSEGV, or SIGBUS *unless* that signal was generated by a
    // kill(2) or raise(3).  Similarly for tgkill(2) on FreeBSD.
    //
    // IOW, user generated signals never generate what we consider to be a
    // "crash".
    //
    // Similarly, ACK signals generated by this monitor.
    if (info->si_code == SI_USER)
    {
        if (log)
            log->Printf ("ProcessMonitor::%s() received signal %s with code %s, pid = %d",
                            __FUNCTION__,
                            monitor->m_process->GetUnixSignals()->GetSignalAsCString (signo),
                            "SI_USER",
                            info->si_pid);
        if (info->si_pid == getpid())
            return ProcessMessage::SignalDelivered(tid, signo);
        else
            return ProcessMessage::Signal(tid, signo);
    }

    if (log)
        log->Printf ("ProcessMonitor::%s() received signal %s", __FUNCTION__, monitor->m_process->GetUnixSignals()->GetSignalAsCString (signo));

    switch (signo)
    {
    case SIGSEGV:
    case SIGILL:
    case SIGFPE:
    case SIGBUS:
        lldb::addr_t fault_addr = reinterpret_cast<lldb::addr_t>(info->si_addr);
        const auto reason = GetCrashReason(*info);
        return ProcessMessage::Crash(tid, reason, signo, fault_addr);
    }

    // Everything else is "normal" and does not require any special action on
    // our part.
    return ProcessMessage::Signal(tid, signo);
}

void
ProcessMonitor::ServeOperation(OperationArgs *args)
{
    ProcessMonitor *monitor = args->m_monitor;

    // We are finised with the arguments and are ready to go.  Sync with the
    // parent thread and start serving operations on the inferior.
    sem_post(&args->m_semaphore);

    for (;;)
    {
        // wait for next pending operation
        sem_wait(&monitor->m_operation_pending);

        monitor->m_operation->Execute(monitor);

        // notify calling thread that operation is complete
        sem_post(&monitor->m_operation_done);
    }
}

void
ProcessMonitor::DoOperation(Operation *op)
{
    Mutex::Locker lock(m_operation_mutex);

    m_operation = op;

    // notify operation thread that an operation is ready to be processed
    sem_post(&m_operation_pending);

    // wait for operation to complete
    sem_wait(&m_operation_done);
}

size_t
ProcessMonitor::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
                           Error &error)
{
    size_t result;
    ReadOperation op(vm_addr, buf, size, error, result);
    DoOperation(&op);
    return result;
}

size_t
ProcessMonitor::WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
                            lldb_private::Error &error)
{
    size_t result;
    WriteOperation op(vm_addr, buf, size, error, result);
    DoOperation(&op);
    return result;
}

bool
ProcessMonitor::ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char* reg_name,
                                  unsigned size, RegisterValue &value)
{
    bool result;
    ReadRegOperation op(tid, offset, size, value, result);
    DoOperation(&op);
    return result;
}

bool
ProcessMonitor::WriteRegisterValue(lldb::tid_t tid, unsigned offset,
                                   const char* reg_name, const RegisterValue &value)
{
    bool result;
    WriteRegOperation op(tid, offset, value, result);
    DoOperation(&op);
    return result;
}

bool
ProcessMonitor::ReadDebugRegisterValue(lldb::tid_t tid, unsigned offset,
                                       const char *reg_name, unsigned size,
                                       lldb_private::RegisterValue &value)
{
    bool result;
    ReadDebugRegOperation op(tid, offset, size, value, result);
    DoOperation(&op);
    return result;
}

bool
ProcessMonitor::WriteDebugRegisterValue(lldb::tid_t tid, unsigned offset,
                                        const char *reg_name,
                                        const lldb_private::RegisterValue &value)
{
    bool result;
    WriteDebugRegOperation op(tid, offset, value, result);
    DoOperation(&op);
    return result;
}

bool
ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
    bool result;
    ReadGPROperation op(tid, buf, result);
    DoOperation(&op);
    return result;
}

bool
ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
    bool result;
    ReadFPROperation op(tid, buf, result);
    DoOperation(&op);
    return result;
}

bool
ProcessMonitor::ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
{
    return false;
}

bool
ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
    bool result;
    WriteGPROperation op(tid, buf, result);
    DoOperation(&op);
    return result;
}

bool
ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
    bool result;
    WriteFPROperation op(tid, buf, result);
    DoOperation(&op);
    return result;
}

bool
ProcessMonitor::WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
{
    return false;
}

bool
ProcessMonitor::ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value)
{
    return false;
}

bool
ProcessMonitor::Resume(lldb::tid_t unused, uint32_t signo)
{
    bool result;
    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));

    if (log) {
        const char *signame = m_process->GetUnixSignals()->GetSignalAsCString (signo);
        if (signame == nullptr)
            signame = "<none>";
        log->Printf("ProcessMonitor::%s() resuming pid %"  PRIu64 " with signal %s",
                    __FUNCTION__, GetPID(), signame);
    }
    ResumeOperation op(signo, result);
    DoOperation(&op);
    if (log)
        log->Printf ("ProcessMonitor::%s() resuming result = %s", __FUNCTION__, result ? "true" : "false");
    return result;
}

bool
ProcessMonitor::SingleStep(lldb::tid_t unused, uint32_t signo)
{
    bool result;
    SingleStepOperation op(signo, result);
    DoOperation(&op);
    return result;
}

bool
ProcessMonitor::Kill()
{
    bool result;
    KillOperation op(result);
    DoOperation(&op);
    return result;
}

bool
ProcessMonitor::GetLwpInfo(lldb::tid_t tid, void *lwpinfo, int &ptrace_err)
{
    bool result;
    LwpInfoOperation op(tid, lwpinfo, result, ptrace_err);
    DoOperation(&op);
    return result;
}

bool
ProcessMonitor::ThreadSuspend(lldb::tid_t tid, bool suspend)
{
    bool result;
    ThreadSuspendOperation op(tid, suspend, result);
    DoOperation(&op);
    return result;
}

bool
ProcessMonitor::GetEventMessage(lldb::tid_t tid, unsigned long *message)
{
    bool result;
    EventMessageOperation op(tid, message, result);
    DoOperation(&op);
    return result;
}

lldb_private::Error
ProcessMonitor::Detach(lldb::tid_t tid)
{
    lldb_private::Error error;
    if (tid != LLDB_INVALID_THREAD_ID)
    {
        DetachOperation op(error);
        DoOperation(&op);
    }
    return error;
}    

bool
ProcessMonitor::DupDescriptor(const FileSpec &file_spec, int fd, int flags)
{
    int target_fd = open(file_spec.GetCString(), flags, 0666);

    if (target_fd == -1)
        return false;

    if (dup2(target_fd, fd) == -1)
        return false;

    return (close(target_fd) == -1) ? false : true;
}

void
ProcessMonitor::StopMonitoringChildProcess()
{
    if (m_monitor_thread.IsJoinable())
    {
        m_monitor_thread.Cancel();
        m_monitor_thread.Join(nullptr);
        m_monitor_thread.Reset();
    }
}

void
ProcessMonitor::StopMonitor()
{
    StopMonitoringChildProcess();
    StopOpThread();
    sem_destroy(&m_operation_pending);
    sem_destroy(&m_operation_done);
    if (m_terminal_fd >= 0) {
        close(m_terminal_fd);
        m_terminal_fd = -1;
    }
}

// FIXME: On Linux, when a new thread is created, we receive to notifications,
// (1) a SIGTRAP|PTRACE_EVENT_CLONE from the main process thread with the
// child thread id as additional information, and (2) a SIGSTOP|SI_USER from
// the new child thread indicating that it has is stopped because we attached.
// We have no guarantee of the order in which these arrive, but we need both
// before we are ready to proceed.  We currently keep a list of threads which
// have sent the initial SIGSTOP|SI_USER event.  Then when we receive the
// SIGTRAP|PTRACE_EVENT_CLONE notification, if the initial stop has not occurred
// we call ProcessMonitor::WaitForInitialTIDStop() to wait for it.
//
// Right now, the above logic is in ProcessPOSIX, so we need a definition of
// this function in the FreeBSD ProcessMonitor implementation even if it isn't
// logically needed.
//
// We really should figure out what actually happens on FreeBSD and move the
// Linux-specific logic out of ProcessPOSIX as needed.

bool
ProcessMonitor::WaitForInitialTIDStop(lldb::tid_t tid)
{
    return true;
}

void
ProcessMonitor::StopOpThread()
{
    if (!m_operation_thread.IsJoinable())
        return;

    m_operation_thread.Cancel();
    m_operation_thread.Join(nullptr);
    m_operation_thread.Reset();
}
