[Lldb-commits] [lldb] r242783 - [NativeProcessLinux] Integrate MainLoop

Pavel Labath labath at google.com
Tue Jul 21 06:20:32 PDT 2015


Author: labath
Date: Tue Jul 21 08:20:32 2015
New Revision: 242783

URL: http://llvm.org/viewvc/llvm-project?rev=242783&view=rev
Log:
[NativeProcessLinux] Integrate MainLoop

Summary:
This commit integrates MainLoop into NativeProcessLinux. By registering a SIGCHLD handler with
the llgs main loop, we can get rid of the special monitor thread in NPL, which saves as a lot of
thread ping-pong when responding to client requests (e.g. qThreadInfo processing time has been
reduced by about 40%). It also makes the code simpler, IMHO.

Reviewers: ovyalov, clayborg, tberghammer, chaoren

Subscribers: lldb-commits

Differential Revision: http://reviews.llvm.org/D11150

This is a resubmission of r242305 after it was reverted due to bad interactions with the stdio
thread.

Modified:
    lldb/trunk/include/lldb/Host/common/NativeProcessProtocol.h
    lldb/trunk/source/Host/common/NativeProcessProtocol.cpp
    lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
    lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h
    lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
    lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
    lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h

Modified: lldb/trunk/include/lldb/Host/common/NativeProcessProtocol.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/common/NativeProcessProtocol.h?rev=242783&r1=242782&r2=242783&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/common/NativeProcessProtocol.h (original)
+++ lldb/trunk/include/lldb/Host/common/NativeProcessProtocol.h Tue Jul 21 08:20:32 2015
@@ -16,6 +16,7 @@
 #include "lldb/lldb-types.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Host/Mutex.h"
+#include "lldb/Host/MainLoop.h"
 #include "llvm/ADT/StringRef.h"
 
 #include "NativeBreakpointList.h"
@@ -284,10 +285,6 @@ namespace lldb_private
         bool
         UnregisterNativeDelegate (NativeDelegate &native_delegate);
 
-        // Called before termination of NativeProcessProtocol's instance.
-        virtual void
-        Terminate ();
-
         virtual Error
         GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec) = 0;
 
@@ -307,6 +304,11 @@ namespace lldb_private
         ///     inferior.  Must outlive the NativeProcessProtocol
         ///     instance.
         ///
+        /// @param[in] mainloop
+        ///     The mainloop instance with which the process can register
+        ///     callbacks. Must outlive the NativeProcessProtocol
+        ///     instance.
+        ///
         /// @param[out] process_sp
         ///     On successful return from the method, this parameter
         ///     contains the shared pointer to the
@@ -320,6 +322,7 @@ namespace lldb_private
         static Error
         Launch (ProcessLaunchInfo &launch_info,
                 NativeDelegate &native_delegate,
+                MainLoop &mainloop,
                 NativeProcessProtocolSP &process_sp);
 
         //------------------------------------------------------------------
@@ -335,6 +338,11 @@ namespace lldb_private
         ///     inferior.  Must outlive the NativeProcessProtocol
         ///     instance.
         ///
+        /// @param[in] mainloop
+        ///     The mainloop instance with which the process can register
+        ///     callbacks. Must outlive the NativeProcessProtocol
+        ///     instance.
+        ///
         /// @param[out] process_sp
         ///     On successful return from the method, this parameter
         ///     contains the shared pointer to the
@@ -348,6 +356,7 @@ namespace lldb_private
         static Error
         Attach (lldb::pid_t pid,
                 NativeDelegate &native_delegate,
+                MainLoop &mainloop,
                 NativeProcessProtocolSP &process_sp);
 
     protected:

Modified: lldb/trunk/source/Host/common/NativeProcessProtocol.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/NativeProcessProtocol.cpp?rev=242783&r1=242782&r2=242783&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/NativeProcessProtocol.cpp (original)
+++ lldb/trunk/source/Host/common/NativeProcessProtocol.cpp Tue Jul 21 08:20:32 2015
@@ -436,12 +436,6 @@ NativeProcessProtocol::DoStopIDBumped (u
     // Default implementation does nothing.
 }
 
-void
-NativeProcessProtocol::Terminate ()
-{
-    // Default implementation does nothing.
-}
-
 #ifndef __linux__
 // These need to be implemented to support lldb-gdb-server on a given platform. Stubs are
 // provided to make the rest of the code link on non-supported platforms.
@@ -449,6 +443,7 @@ NativeProcessProtocol::Terminate ()
 Error
 NativeProcessProtocol::Launch (ProcessLaunchInfo &launch_info,
         NativeDelegate &native_delegate,
+        MainLoop &mainloop,
         NativeProcessProtocolSP &process_sp)
 {
     llvm_unreachable("Platform has no NativeProcessProtocol support");
@@ -457,6 +452,7 @@ NativeProcessProtocol::Launch (ProcessLa
 Error
 NativeProcessProtocol::Attach (lldb::pid_t pid,
         NativeDelegate &native_delegate,
+        MainLoop &mainloop,
         NativeProcessProtocolSP &process_sp)
 {
     llvm_unreachable("Platform has no NativeProcessProtocol support");

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp?rev=242783&r1=242782&r2=242783&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp Tue Jul 21 08:20:32 2015
@@ -11,7 +11,6 @@
 
 // C Includes
 #include <errno.h>
-#include <semaphore.h>
 #include <string.h>
 #include <stdint.h>
 #include <unistd.h>
@@ -213,157 +212,8 @@ namespace
         }
     }
 
-    //------------------------------------------------------------------------------
-    // Static implementations of NativeProcessLinux::ReadMemory and
-    // NativeProcessLinux::WriteMemory.  This enables mutual recursion between these
-    // functions without needed to go thru the thread funnel.
-
-    Error
-    DoReadMemory(
-        lldb::pid_t pid,
-        lldb::addr_t vm_addr,
-        void *buf,
-        size_t size,
-        size_t &bytes_read)
-    {
-        // ptrace word size is determined by the host, not the child
-        static const unsigned word_size = sizeof(void*);
-        unsigned char *dst = static_cast<unsigned char*>(buf);
-        size_t remainder;
-        long data;
-
-        Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL));
-        if (log)
-            ProcessPOSIXLog::IncNestLevel();
-        if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY))
-            log->Printf ("NativeProcessLinux::%s(%" PRIu64 ", %d, %p, %p, %zd, _)", __FUNCTION__,
-                    pid, word_size, (void*)vm_addr, buf, size);
-
-        assert(sizeof(data) >= word_size);
-        for (bytes_read = 0; bytes_read < size; bytes_read += remainder)
-        {
-            Error error = NativeProcessLinux::PtraceWrapper(PTRACE_PEEKDATA, pid, (void*)vm_addr, nullptr, 0, &data);
-            if (error.Fail())
-            {
-                if (log)
-                    ProcessPOSIXLog::DecNestLevel();
-                return error;
-            }
-
-            remainder = size - bytes_read;
-            remainder = remainder > word_size ? word_size : remainder;
-
-            // Copy the data into our buffer
-            for (unsigned i = 0; i < remainder; ++i)
-                dst[i] = ((data >> i*8) & 0xFF);
-
-            if (log && ProcessPOSIXLog::AtTopNestLevel() &&
-                    (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
-                            (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
-                                    size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
-            {
-                uintptr_t print_dst = 0;
-                // Format bytes from data by moving into print_dst for log output
-                for (unsigned i = 0; i < remainder; ++i)
-                    print_dst |= (((data >> i*8) & 0xFF) << i*8);
-                log->Printf ("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
-                        (void*)vm_addr, print_dst, (unsigned long)data);
-            }
-            vm_addr += word_size;
-            dst += word_size;
-        }
-
-        if (log)
-            ProcessPOSIXLog::DecNestLevel();
-        return Error();
-    }
-
-    Error
-    DoWriteMemory(
-        lldb::pid_t pid,
-        lldb::addr_t vm_addr,
-        const void *buf,
-        size_t size,
-        size_t &bytes_written)
-    {
-        // ptrace word size is determined by the host, not the child
-        static const unsigned word_size = sizeof(void*);
-        const unsigned char *src = static_cast<const unsigned char*>(buf);
-        size_t remainder;
-        Error error;
-
-        Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL));
-        if (log)
-            ProcessPOSIXLog::IncNestLevel();
-        if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY))
-            log->Printf ("NativeProcessLinux::%s(%" PRIu64 ", %u, %p, %p, %" PRIu64 ")", __FUNCTION__,
-                    pid, word_size, (void*)vm_addr, buf, size);
-
-        for (bytes_written = 0; bytes_written < size; bytes_written += remainder)
-        {
-            remainder = size - bytes_written;
-            remainder = remainder > word_size ? word_size : remainder;
-
-            if (remainder == word_size)
-            {
-                unsigned long data = 0;
-                assert(sizeof(data) >= word_size);
-                for (unsigned i = 0; i < word_size; ++i)
-                    data |= (unsigned long)src[i] << i*8;
-
-                if (log && ProcessPOSIXLog::AtTopNestLevel() &&
-                        (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
-                                (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
-                                        size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
-                    log->Printf ("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
-                            (void*)vm_addr, *(const unsigned long*)src, data);
-
-                error = NativeProcessLinux::PtraceWrapper(PTRACE_POKEDATA, pid, (void*)vm_addr, (void*)data);
-                if (error.Fail())
-                {
-                    if (log)
-                        ProcessPOSIXLog::DecNestLevel();
-                    return error;
-                }
-            }
-            else
-            {
-                unsigned char buff[8];
-                size_t bytes_read;
-                error = DoReadMemory(pid, vm_addr, buff, word_size, bytes_read);
-                if (error.Fail())
-                {
-                    if (log)
-                        ProcessPOSIXLog::DecNestLevel();
-                    return error;
-                }
-
-                memcpy(buff, src, remainder);
-
-                size_t bytes_written_rec;
-                error = DoWriteMemory(pid, vm_addr, buff, word_size, bytes_written_rec);
-                if (error.Fail())
-                {
-                    if (log)
-                        ProcessPOSIXLog::DecNestLevel();
-                    return error;
-                }
-
-                if (log && ProcessPOSIXLog::AtTopNestLevel() &&
-                        (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
-                                (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
-                                        size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
-                    log->Printf ("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
-                            (void*)vm_addr, *(const unsigned long*)src, *(unsigned long*)buff);
-            }
-
-            vm_addr += word_size;
-            src += word_size;
-        }
-        if (log)
-            ProcessPOSIXLog::DecNestLevel();
-        return error;
-    }
+    static constexpr unsigned k_ptrace_word_size = sizeof(void*);
+    static_assert(sizeof(long) >= k_ptrace_word_size, "Size of long must be larger than ptrace word size");
 } // end of anonymous namespace
 
 // Simple helper function to ensure flags are enabled on the given file
@@ -389,409 +239,6 @@ EnsureFDFlags(int fd, int flags)
     return error;
 }
 
-// This class encapsulates the privileged thread which performs all ptrace and wait operations on
-// the inferior. The thread consists of a main loop which waits for events and processes them
-//   - SIGCHLD (delivered over a signalfd file descriptor): These signals notify us of events in
-//     the inferior process. Upon receiving this signal we do a waitpid to get more information
-//     and dispatch to NativeProcessLinux::MonitorCallback.
-//   - requests for ptrace operations: These initiated via the DoOperation method, which funnels
-//     them to the Monitor thread via m_operation member. The Monitor thread is signaled over a
-//     pipe, and the completion of the operation is signalled over the semaphore.
-//   - thread exit event: this is signaled from the Monitor destructor by closing the write end
-//     of the command pipe.
-class NativeProcessLinux::Monitor
-{
-private:
-    // The initial monitor operation (launch or attach). It returns a inferior process id.
-    std::unique_ptr<InitialOperation> m_initial_operation_up;
-
-    ::pid_t                           m_child_pid = -1;
-    NativeProcessLinux              * m_native_process;
-
-    enum { READ, WRITE };
-    int        m_pipefd[2] = {-1, -1};
-    int        m_signal_fd = -1;
-    HostThread m_thread;
-
-    // current operation which must be executed on the priviliged thread
-    Mutex            m_operation_mutex;
-    const Operation *m_operation = nullptr;
-    sem_t            m_operation_sem;
-    Error            m_operation_error;
-
-    unsigned   m_operation_nesting_level = 0;
-
-    static constexpr char operation_command   = 'o';
-    static constexpr char begin_block_command = '{';
-    static constexpr char end_block_command   = '}';
-
-    void
-    HandleSignals();
-
-    void
-    HandleWait();
-
-    // Returns true if the thread should exit.
-    bool
-    HandleCommands();
-
-    void
-    MainLoop();
-
-    static void *
-    RunMonitor(void *arg);
-
-    Error
-    WaitForAck();
-
-    void
-    BeginOperationBlock()
-    {
-        write(m_pipefd[WRITE], &begin_block_command, sizeof operation_command);
-        WaitForAck();
-    }
-
-    void
-    EndOperationBlock()
-    {
-        write(m_pipefd[WRITE], &end_block_command, sizeof operation_command);
-        WaitForAck();
-    }
-
-public:
-    Monitor(const InitialOperation &initial_operation,
-            NativeProcessLinux *native_process)
-        : m_initial_operation_up(new InitialOperation(initial_operation)),
-          m_native_process(native_process)
-    {
-        sem_init(&m_operation_sem, 0, 0);
-    }
-
-    ~Monitor();
-
-    Error
-    Initialize();
-
-    void
-    Terminate();
-
-    Error
-    DoOperation(const Operation &op);
-
-    class ScopedOperationLock {
-        Monitor &m_monitor;
-
-    public:
-        ScopedOperationLock(Monitor &monitor)
-            : m_monitor(monitor)
-        { m_monitor.BeginOperationBlock(); }
-
-        ~ScopedOperationLock()
-        { m_monitor.EndOperationBlock(); }
-    };
-};
-constexpr char NativeProcessLinux::Monitor::operation_command;
-constexpr char NativeProcessLinux::Monitor::begin_block_command;
-constexpr char NativeProcessLinux::Monitor::end_block_command;
-
-Error
-NativeProcessLinux::Monitor::Initialize()
-{
-    Error error;
-
-    // We get a SIGCHLD every time something interesting happens with the inferior. We shall be
-    // listening for these signals over a signalfd file descriptors. This allows us to wait for
-    // multiple kinds of events with select.
-    sigset_t signals;
-    sigemptyset(&signals);
-    sigaddset(&signals, SIGCHLD);
-    m_signal_fd = signalfd(-1, &signals, SFD_NONBLOCK | SFD_CLOEXEC);
-    if (m_signal_fd < 0)
-    {
-        return Error("NativeProcessLinux::Monitor::%s failed due to signalfd failure. Monitoring the inferior will be impossible: %s",
-                    __FUNCTION__, strerror(errno));
-
-    }
-
-    if (pipe2(m_pipefd, O_CLOEXEC) == -1)
-    {
-        error.SetErrorToErrno();
-        return error;
-    }
-
-    if ((error = EnsureFDFlags(m_pipefd[READ], O_NONBLOCK)).Fail()) {
-        return error;
-    }
-
-    static const char g_thread_name[] = "lldb.process.nativelinux.monitor";
-    m_thread = ThreadLauncher::LaunchThread(g_thread_name, Monitor::RunMonitor, this, nullptr);
-    if (!m_thread.IsJoinable())
-        return Error("Failed to create monitor thread for NativeProcessLinux.");
-
-    // Wait for initial operation to complete.
-    return WaitForAck();
-}
-
-Error
-NativeProcessLinux::Monitor::DoOperation(const Operation &op)
-{
-    if (m_thread.EqualsThread(pthread_self())) {
-        // If we're on the Monitor thread, we can simply execute the operation.
-        return op();
-    }
-
-    // Otherwise we need to pass the operation to the Monitor thread so it can handle it.
-    Mutex::Locker lock(m_operation_mutex);
-
-    m_operation = &op;
-
-    // notify the thread that an operation is ready to be processed
-    write(m_pipefd[WRITE], &operation_command, sizeof operation_command);
-
-    return WaitForAck();
-}
-
-void
-NativeProcessLinux::Monitor::Terminate()
-{
-    if (m_pipefd[WRITE] >= 0)
-    {
-        close(m_pipefd[WRITE]);
-        m_pipefd[WRITE] = -1;
-    }
-    if (m_thread.IsJoinable())
-        m_thread.Join(nullptr);
-}
-
-NativeProcessLinux::Monitor::~Monitor()
-{
-    Terminate();
-    if (m_pipefd[READ] >= 0)
-        close(m_pipefd[READ]);
-    if (m_signal_fd >= 0)
-        close(m_signal_fd);
-    sem_destroy(&m_operation_sem);
-}
-
-void
-NativeProcessLinux::Monitor::HandleSignals()
-{
-    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
-    // We don't really care about the content of the SIGCHLD siginfo structure, as we will get
-    // all the information from waitpid(). We just need to read all the signals so that we can
-    // sleep next time we reach select().
-    while (true)
-    {
-        signalfd_siginfo info;
-        ssize_t size = read(m_signal_fd, &info, sizeof info);
-        if (size == -1)
-        {
-            if (errno == EAGAIN || errno == EWOULDBLOCK)
-                break; // We are done.
-            if (errno == EINTR)
-                continue;
-            if (log)
-                log->Printf("NativeProcessLinux::Monitor::%s reading from signalfd file descriptor failed: %s",
-                        __FUNCTION__, strerror(errno));
-            break;
-        }
-        if (size != sizeof info)
-        {
-            // We got incomplete information structure. This should not happen, let's just log
-            // that.
-            if (log)
-                log->Printf("NativeProcessLinux::Monitor::%s reading from signalfd file descriptor returned incomplete data: "
-                        "structure size is %zd, read returned %zd bytes",
-                        __FUNCTION__, sizeof info, size);
-            break;
-        }
-        if (log)
-            log->Printf("NativeProcessLinux::Monitor::%s received signal %s(%d).", __FUNCTION__,
-                Host::GetSignalAsCString(info.ssi_signo), info.ssi_signo);
-    }
-}
-
-void
-NativeProcessLinux::Monitor::HandleWait()
-{
-    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-    // Process all pending waitpid notifications.
-    while (true)
-    {
-        int status = -1;
-        ::pid_t wait_pid = waitpid(-1, &status, __WALL | __WNOTHREAD | WNOHANG);
-
-        if (wait_pid == 0)
-            break; // We are done.
-
-        if (wait_pid == -1)
-        {
-            if (errno == EINTR)
-                continue;
-
-            if (log)
-              log->Printf("NativeProcessLinux::Monitor::%s waitpid (-1, &status, __WALL | __WNOTHREAD | WNOHANG) failed: %s",
-                      __FUNCTION__, strerror(errno));
-            break;
-        }
-
-        bool exited = false;
-        int signal = 0;
-        int exit_status = 0;
-        const char *status_cstr = NULL;
-        if (WIFSTOPPED(status))
-        {
-            signal = WSTOPSIG(status);
-            status_cstr = "STOPPED";
-        }
-        else if (WIFEXITED(status))
-        {
-            exit_status = WEXITSTATUS(status);
-            status_cstr = "EXITED";
-            exited = true;
-        }
-        else if (WIFSIGNALED(status))
-        {
-            signal = WTERMSIG(status);
-            status_cstr = "SIGNALED";
-            if (wait_pid == m_child_pid) {
-                exited = true;
-                exit_status = -1;
-            }
-        }
-        else
-            status_cstr = "(\?\?\?)";
-
-        if (log)
-            log->Printf("NativeProcessLinux::Monitor::%s: waitpid (-1, &status, __WALL | __WNOTHREAD | WNOHANG)"
-                "=> pid = %" PRIi32 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
-                __FUNCTION__, wait_pid, status, status_cstr, signal, exit_status);
-
-        m_native_process->MonitorCallback (wait_pid, exited, signal, exit_status);
-    }
-}
-
-bool
-NativeProcessLinux::Monitor::HandleCommands()
-{
-    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-
-    while (true)
-    {
-        char command = 0;
-        ssize_t size = read(m_pipefd[READ], &command, sizeof command);
-        if (size == -1)
-        {
-            if (errno == EAGAIN || errno == EWOULDBLOCK)
-                return false;
-            if (errno == EINTR)
-                continue;
-            if (log)
-                log->Printf("NativeProcessLinux::Monitor::%s exiting because read from command file descriptor failed: %s", __FUNCTION__, strerror(errno));
-            return true;
-        }
-        if (size == 0) // end of file - write end closed
-        {
-            if (log)
-                log->Printf("NativeProcessLinux::Monitor::%s exit command received, exiting...", __FUNCTION__);
-            assert(m_operation_nesting_level == 0 && "Unbalanced begin/end block commands detected");
-            return true; // We are done.
-        }
-
-        switch (command)
-        {
-        case operation_command:
-            m_operation_error = (*m_operation)();
-            break;
-        case begin_block_command:
-            ++m_operation_nesting_level;
-            break;
-        case end_block_command:
-            assert(m_operation_nesting_level > 0);
-            --m_operation_nesting_level;
-            break;
-        default:
-            if (log)
-                log->Printf("NativeProcessLinux::Monitor::%s received unknown command '%c'",
-                        __FUNCTION__, command);
-        }
-
-        // notify calling thread that the command has been processed
-        sem_post(&m_operation_sem);
-    }
-}
-
-void
-NativeProcessLinux::Monitor::MainLoop()
-{
-    ::pid_t child_pid = (*m_initial_operation_up)(m_operation_error);
-    m_initial_operation_up.reset();
-    m_child_pid = child_pid;
-    sem_post(&m_operation_sem);
-
-    while (true)
-    {
-        fd_set fds;
-        FD_ZERO(&fds);
-        // Only process waitpid events if we are outside of an operation block. Any pending
-        // events will be processed after we leave the block.
-        if (m_operation_nesting_level == 0)
-            FD_SET(m_signal_fd, &fds);
-        FD_SET(m_pipefd[READ], &fds);
-
-        int max_fd = std::max(m_signal_fd, m_pipefd[READ]) + 1;
-        int r = select(max_fd, &fds, nullptr, nullptr, nullptr);
-        if (r < 0)
-        {
-            if (errno == EINTR)
-                continue;
-
-            Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
-            if (log)
-                log->Printf("NativeProcessLinux::Monitor::%s exiting because select failed: %s",
-                        __FUNCTION__, strerror(errno));
-            return;
-        }
-
-        if (FD_ISSET(m_pipefd[READ], &fds))
-        {
-            if (HandleCommands())
-                return;
-        }
-
-        if (FD_ISSET(m_signal_fd, &fds))
-        {
-            HandleSignals();
-            HandleWait();
-        }
-    }
-}
-
-Error
-NativeProcessLinux::Monitor::WaitForAck()
-{
-    Error error;
-    while (sem_wait(&m_operation_sem) != 0)
-    {
-        if (errno == EINTR)
-            continue;
-
-        error.SetErrorToErrno();
-        return error;
-    }
-
-    return m_operation_error;
-}
-
-void *
-NativeProcessLinux::Monitor::RunMonitor(void *arg)
-{
-    static_cast<Monitor *>(arg)->MainLoop();
-    return nullptr;
-}
-
-
 NativeProcessLinux::LaunchArgs::LaunchArgs(Module *module,
                                        char const **argv,
                                        char const **envp,
@@ -822,6 +269,7 @@ Error
 NativeProcessProtocol::Launch (
     ProcessLaunchInfo &launch_info,
     NativeProcessProtocol::NativeDelegate &native_delegate,
+    MainLoop &mainloop,
     NativeProcessProtocolSP &native_process_sp)
 {
     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
@@ -908,6 +356,7 @@ NativeProcessProtocol::Launch (
     }
 
     std::static_pointer_cast<NativeProcessLinux> (native_process_sp)->LaunchInferior (
+            mainloop,
             exe_module_sp.get(),
             launch_info.GetArguments ().GetConstArgumentVector (),
             launch_info.GetEnvironmentEntries ().GetConstArgumentVector (),
@@ -935,6 +384,7 @@ Error
 NativeProcessProtocol::Attach (
     lldb::pid_t pid,
     NativeProcessProtocol::NativeDelegate &native_delegate,
+    MainLoop &mainloop,
     NativeProcessProtocolSP &native_process_sp)
 {
     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
@@ -961,7 +411,7 @@ NativeProcessProtocol::Attach (
         return error;
     }
 
-    native_process_linux_sp->AttachToInferior (pid, error);
+    native_process_linux_sp->AttachToInferior (mainloop, pid, error);
     if (!error.Success ())
         return error;
 
@@ -982,12 +432,9 @@ NativeProcessLinux::NativeProcessLinux (
 {
 }
 
-//------------------------------------------------------------------------------
-// NativeProcessLinux spawns a new thread which performs all operations on the inferior process.
-// Refer to Monitor and Operation classes to see why this is necessary.
-//------------------------------------------------------------------------------
 void
 NativeProcessLinux::LaunchInferior (
+    MainLoop &mainloop,
     Module *module,
     const char *argv[],
     const char *envp[],
@@ -998,6 +445,11 @@ NativeProcessLinux::LaunchInferior (
     const ProcessLaunchInfo &launch_info,
     Error &error)
 {
+    m_sigchld_handle = mainloop.RegisterSignal(SIGCHLD,
+            [this] (MainLoopBase &) { SigchldHandler(); }, error);
+    if (! m_sigchld_handle)
+        return;
+
     if (module)
         m_arch = module->GetArchitecture ();
 
@@ -1011,18 +463,21 @@ NativeProcessLinux::LaunchInferior (
                        working_dir,
                        launch_info));
 
-    StartMonitorThread ([&] (Error &e) { return Launch(args.get(), e); }, error);
-    if (!error.Success ())
-        return;
+    Launch(args.get(), error);
 }
 
 void
-NativeProcessLinux::AttachToInferior (lldb::pid_t pid, Error &error)
+NativeProcessLinux::AttachToInferior (MainLoop &mainloop, lldb::pid_t pid, Error &error)
 {
     Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
     if (log)
         log->Printf ("NativeProcessLinux::%s (pid = %" PRIi64 ")", __FUNCTION__, pid);
 
+    m_sigchld_handle = mainloop.RegisterSignal(SIGCHLD,
+            [this] (MainLoopBase &) { SigchldHandler(); }, error);
+    if (! m_sigchld_handle)
+        return;
+
     // We can use the Host for everything except the ResolveExecutable portion.
     PlatformSP platform_sp = Platform::GetHostPlatform ();
     if (!platform_sp)
@@ -1060,15 +515,7 @@ NativeProcessLinux::AttachToInferior (ll
     m_pid = pid;
     SetState(eStateAttaching);
 
-    StartMonitorThread ([=] (Error &e) { return Attach(pid, e); }, error);
-    if (!error.Success ())
-        return;
-}
-
-void
-NativeProcessLinux::Terminate ()
-{
-    m_monitor_up->Terminate();
+    Attach(pid, error);
 }
 
 ::pid_t
@@ -2290,7 +1737,6 @@ NativeProcessLinux::Resume (const Resume
 
     bool software_single_step = !SupportHardwareSingleStepping();
 
-    Monitor::ScopedOperationLock monitor_lock(*m_monitor_up);
     Mutex::Locker locker (m_threads_mutex);
 
     if (software_single_step)
@@ -2410,7 +1856,7 @@ NativeProcessLinux::Detach ()
         error = Detach (GetID ());
 
     // Stop monitoring the inferior.
-    m_monitor_up->Terminate();
+    m_sigchld_handle.reset();
 
     // No error.
     return error;
@@ -2445,7 +1891,6 @@ NativeProcessLinux::Interrupt ()
     if (log)
         log->Printf ("NativeProcessLinux::%s selecting running thread for interrupt target", __FUNCTION__);
 
-    Monitor::ScopedOperationLock monitor_lock(*m_monitor_up);
     Mutex::Locker locker (m_threads_mutex);
 
     for (auto thread_sp : m_threads)
@@ -3101,24 +2546,6 @@ NativeProcessLinux::GetCrashReasonForSIG
 #endif
 
 Error
-NativeProcessLinux::SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware)
-{
-    // The base SetWatchpoint will end up executing monitor operations. Let's lock the monitor
-    // for it.
-    Monitor::ScopedOperationLock monitor_lock(*m_monitor_up);
-    return NativeProcessProtocol::SetWatchpoint(addr, size, watch_flags, hardware);
-}
-
-Error
-NativeProcessLinux::RemoveWatchpoint (lldb::addr_t addr)
-{
-    // The base RemoveWatchpoint will end up executing monitor operations. Let's lock the monitor
-    // for it.
-    Monitor::ScopedOperationLock monitor_lock(*m_monitor_up);
-    return NativeProcessProtocol::RemoveWatchpoint(addr);
-}
-
-Error
 NativeProcessLinux::ReadMemory (lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read)
 {
     if (ProcessVmReadvSupported()) {
@@ -3147,7 +2574,52 @@ NativeProcessLinux::ReadMemory (lldb::ad
         //     the call failed for some reason, let's retry the read using ptrace api.
     }
 
-    return DoOperation([&] { return DoReadMemory(GetID(), addr, buf, size, bytes_read); });
+    unsigned char *dst = static_cast<unsigned char*>(buf);
+    size_t remainder;
+    long data;
+
+    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL));
+    if (log)
+        ProcessPOSIXLog::IncNestLevel();
+    if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY))
+        log->Printf ("NativeProcessLinux::%s(%p, %p, %zd, _)", __FUNCTION__, (void*)addr, buf, size);
+
+    for (bytes_read = 0; bytes_read < size; bytes_read += remainder)
+    {
+        Error error = NativeProcessLinux::PtraceWrapper(PTRACE_PEEKDATA, GetID(), (void*)addr, nullptr, 0, &data);
+        if (error.Fail())
+        {
+            if (log)
+                ProcessPOSIXLog::DecNestLevel();
+            return error;
+        }
+
+        remainder = size - bytes_read;
+        remainder = remainder > k_ptrace_word_size ? k_ptrace_word_size : remainder;
+
+        // Copy the data into our buffer
+        for (unsigned i = 0; i < remainder; ++i)
+            dst[i] = ((data >> i*8) & 0xFF);
+
+        if (log && ProcessPOSIXLog::AtTopNestLevel() &&
+                (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
+                        (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
+                                size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
+        {
+            uintptr_t print_dst = 0;
+            // Format bytes from data by moving into print_dst for log output
+            for (unsigned i = 0; i < remainder; ++i)
+                print_dst |= (((data >> i*8) & 0xFF) << i*8);
+            log->Printf ("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
+                    (void*)addr, print_dst, (unsigned long)data);
+        }
+        addr += k_ptrace_word_size;
+        dst += k_ptrace_word_size;
+    }
+
+    if (log)
+        ProcessPOSIXLog::DecNestLevel();
+    return Error();
 }
 
 Error
@@ -3161,7 +2633,79 @@ NativeProcessLinux::ReadMemoryWithoutTra
 Error
 NativeProcessLinux::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written)
 {
-    return DoOperation([&] { return DoWriteMemory(GetID(), addr, buf, size, bytes_written); });
+    const unsigned char *src = static_cast<const unsigned char*>(buf);
+    size_t remainder;
+    Error error;
+
+    Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL));
+    if (log)
+        ProcessPOSIXLog::IncNestLevel();
+    if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY))
+        log->Printf ("NativeProcessLinux::%s(%p, %p, %" PRIu64 ")", __FUNCTION__, (void*)addr, buf, size);
+
+    for (bytes_written = 0; bytes_written < size; bytes_written += remainder)
+    {
+        remainder = size - bytes_written;
+        remainder = remainder > k_ptrace_word_size ? k_ptrace_word_size : remainder;
+
+        if (remainder == k_ptrace_word_size)
+        {
+            unsigned long data = 0;
+            for (unsigned i = 0; i < k_ptrace_word_size; ++i)
+                data |= (unsigned long)src[i] << i*8;
+
+            if (log && ProcessPOSIXLog::AtTopNestLevel() &&
+                    (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
+                            (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
+                                    size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
+                log->Printf ("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
+                        (void*)addr, *(const unsigned long*)src, data);
+
+            error = NativeProcessLinux::PtraceWrapper(PTRACE_POKEDATA, GetID(), (void*)addr, (void*)data);
+            if (error.Fail())
+            {
+                if (log)
+                    ProcessPOSIXLog::DecNestLevel();
+                return error;
+            }
+        }
+        else
+        {
+            unsigned char buff[8];
+            size_t bytes_read;
+            error = ReadMemory(addr, buff, k_ptrace_word_size, bytes_read);
+            if (error.Fail())
+            {
+                if (log)
+                    ProcessPOSIXLog::DecNestLevel();
+                return error;
+            }
+
+            memcpy(buff, src, remainder);
+
+            size_t bytes_written_rec;
+            error = WriteMemory(addr, buff, k_ptrace_word_size, bytes_written_rec);
+            if (error.Fail())
+            {
+                if (log)
+                    ProcessPOSIXLog::DecNestLevel();
+                return error;
+            }
+
+            if (log && ProcessPOSIXLog::AtTopNestLevel() &&
+                    (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_LONG) ||
+                            (log->GetMask().Test(POSIX_LOG_MEMORY_DATA_SHORT) &&
+                                    size <= POSIX_LOG_MEMORY_SHORT_BYTES)))
+                log->Printf ("NativeProcessLinux::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
+                        (void*)addr, *(const unsigned long*)src, *(unsigned long*)buff);
+        }
+
+        addr += k_ptrace_word_size;
+        src += k_ptrace_word_size;
+    }
+    if (log)
+        ProcessPOSIXLog::DecNestLevel();
+    return error;
 }
 
 Error
@@ -3180,7 +2724,7 @@ NativeProcessLinux::Resume (lldb::tid_t
     if (signo != LLDB_INVALID_SIGNAL_NUMBER)
         data = signo;
 
-    Error error = DoOperation([&] { return PtraceWrapper(PTRACE_CONT, tid, nullptr, (void*)data); });
+    Error error = PtraceWrapper(PTRACE_CONT, tid, nullptr, (void*)data);
 
     if (log)
         log->Printf ("NativeProcessLinux::%s() resuming thread = %"  PRIu64 " result = %s", __FUNCTION__, tid, error.Success() ? "true" : "false");
@@ -3195,19 +2739,19 @@ NativeProcessLinux::SingleStep(lldb::tid
     if (signo != LLDB_INVALID_SIGNAL_NUMBER)
         data = signo;
 
-    return DoOperation([&] { return PtraceWrapper(PTRACE_SINGLESTEP, tid, nullptr, (void*)data); });
+    return PtraceWrapper(PTRACE_SINGLESTEP, tid, nullptr, (void*)data);
 }
 
 Error
 NativeProcessLinux::GetSignalInfo(lldb::tid_t tid, void *siginfo)
 {
-    return DoOperation([&] { return PtraceWrapper(PTRACE_GETSIGINFO, tid, nullptr, siginfo); });
+    return PtraceWrapper(PTRACE_GETSIGINFO, tid, nullptr, siginfo);
 }
 
 Error
 NativeProcessLinux::GetEventMessage(lldb::tid_t tid, unsigned long *message)
 {
-    return DoOperation([&] { return PtraceWrapper(PTRACE_GETEVENTMSG, tid, nullptr, message); });
+    return PtraceWrapper(PTRACE_GETEVENTMSG, tid, nullptr, message);
 }
 
 Error
@@ -3216,7 +2760,7 @@ NativeProcessLinux::Detach(lldb::tid_t t
     if (tid == LLDB_INVALID_THREAD_ID)
         return Error();
 
-    return DoOperation([&] { return PtraceWrapper(PTRACE_DETACH, tid); });
+    return PtraceWrapper(PTRACE_DETACH, tid);
 }
 
 bool
@@ -3233,16 +2777,6 @@ NativeProcessLinux::DupDescriptor(const
     return (close(target_fd) == -1) ? false : true;
 }
 
-void
-NativeProcessLinux::StartMonitorThread(const InitialOperation &initial_operation, Error &error)
-{
-    m_monitor_up.reset(new Monitor(initial_operation, this));
-    error = m_monitor_up->Initialize();
-    if (error.Fail()) {
-        m_monitor_up.reset();
-    }
-}
-
 bool
 NativeProcessLinux::HasThreadNoLock (lldb::tid_t thread_id)
 {
@@ -3711,10 +3245,65 @@ NativeProcessLinux::ThreadWasCreated (ll
     }
 }
 
-Error
-NativeProcessLinux::DoOperation(const Operation &op)
+void
+NativeProcessLinux::SigchldHandler()
 {
-    return m_monitor_up->DoOperation(op);
+    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+    // Process all pending waitpid notifications.
+    while (true)
+    {
+        int status = -1;
+        ::pid_t wait_pid = waitpid(-1, &status, __WALL | __WNOTHREAD | WNOHANG);
+
+        if (wait_pid == 0)
+            break; // We are done.
+
+        if (wait_pid == -1)
+        {
+            if (errno == EINTR)
+                continue;
+
+            Error error(errno, eErrorTypePOSIX);
+            if (log)
+                log->Printf("NativeProcessLinux::%s waitpid (-1, &status, __WALL | __WNOTHREAD | WNOHANG) failed: %s",
+                        __FUNCTION__, error.AsCString());
+            break;
+        }
+
+        bool exited = false;
+        int signal = 0;
+        int exit_status = 0;
+        const char *status_cstr = nullptr;
+        if (WIFSTOPPED(status))
+        {
+            signal = WSTOPSIG(status);
+            status_cstr = "STOPPED";
+        }
+        else if (WIFEXITED(status))
+        {
+            exit_status = WEXITSTATUS(status);
+            status_cstr = "EXITED";
+            exited = true;
+        }
+        else if (WIFSIGNALED(status))
+        {
+            signal = WTERMSIG(status);
+            status_cstr = "SIGNALED";
+            if (wait_pid == static_cast<::pid_t>(GetID())) {
+                exited = true;
+                exit_status = -1;
+            }
+        }
+        else
+            status_cstr = "(\?\?\?)";
+
+        if (log)
+            log->Printf("NativeProcessLinux::%s: waitpid (-1, &status, __WALL | __WNOTHREAD | WNOHANG)"
+                "=> pid = %" PRIi32 ", status = 0x%8.8x (%s), signal = %i, exit_state = %i",
+                __FUNCTION__, wait_pid, status, status_cstr, signal, exit_status);
+
+        MonitorCallback (wait_pid, exited, signal, exit_status);
+    }
 }
 
 // Wrapper for ptrace to catch errors and log calls.

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h?rev=242783&r1=242782&r2=242783&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.h Tue Jul 21 08:20:32 2015
@@ -43,25 +43,16 @@ namespace process_linux {
         friend Error
         NativeProcessProtocol::Launch (ProcessLaunchInfo &launch_info,
                 NativeDelegate &native_delegate,
+                MainLoop &mainloop,
                 NativeProcessProtocolSP &process_sp);
 
         friend Error
         NativeProcessProtocol::Attach (lldb::pid_t pid,
-            NativeProcessProtocol::NativeDelegate &native_delegate,
-            NativeProcessProtocolSP &native_process_sp);
+                NativeProcessProtocol::NativeDelegate &native_delegate,
+                MainLoop &mainloop,
+                NativeProcessProtocolSP &process_sp);
 
     public:
-        //------------------------------------------------------------------------------
-        /// @class Operation
-        /// @brief Represents a NativeProcessLinux operation.
-        ///
-        /// Under Linux, 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 NativeProcessLinux 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.
-        typedef std::function<Error()> Operation;
-
         // ---------------------------------------------------------------------
         // NativeProcessProtocol Interface
         // ---------------------------------------------------------------------
@@ -113,18 +104,9 @@ namespace process_linux {
         Error
         SetBreakpoint (lldb::addr_t addr, uint32_t size, bool hardware) override;
 
-        Error
-        SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) override;
-
-        Error
-        RemoveWatchpoint (lldb::addr_t addr) override;
-
         void
         DoStopIDBumped (uint32_t newBumpId) override;
 
-        void
-        Terminate () override;
-
         Error
         GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec) override;
 
@@ -134,9 +116,6 @@ namespace process_linux {
         // ---------------------------------------------------------------------
         // Interface used by NativeRegisterContext-derived classes.
         // ---------------------------------------------------------------------
-        Error
-        DoOperation(const Operation &op);
-
         static Error
         PtraceWrapper(int req,
                       lldb::pid_t pid,
@@ -154,12 +133,9 @@ namespace process_linux {
 
     private:
 
-        class Monitor;
-
+        MainLoop::SignalHandleUP m_sigchld_handle;
         ArchSpec m_arch;
 
-        std::unique_ptr<Monitor> m_monitor_up;
-
         LazyBool m_supports_mem_region;
         std::vector<MemoryRegionInfo> m_mem_region_cache;
         Mutex m_mem_region_cache_mutex;
@@ -206,6 +182,7 @@ namespace process_linux {
         /// implementation of Process::DoLaunch.
         void
         LaunchInferior (
+            MainLoop &mainloop,
             Module *module,
             char const *argv[],
             char const *envp[],
@@ -219,10 +196,7 @@ namespace process_linux {
         /// Attaches to an existing process.  Forms the
         /// implementation of Process::DoAttach
         void
-        AttachToInferior (lldb::pid_t pid, Error &error);
-
-        void
-        StartMonitorThread(const InitialOperation &operation, Error &error);
+        AttachToInferior (MainLoop &mainloop, lldb::pid_t pid, Error &error);
 
         ::pid_t
         Launch(LaunchArgs *args, Error &error);
@@ -370,6 +344,9 @@ namespace process_linux {
         void
         ThreadWasCreated (lldb::tid_t tid);
 
+        void
+        SigchldHandler();
+
         // Member variables.
         PendingNotificationUP m_pending_notification_up;
     };

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp?rev=242783&r1=242782&r2=242783&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux.cpp Tue Jul 21 08:20:32 2015
@@ -50,14 +50,7 @@ NativeRegisterContextLinux::ReadRegister
     if (!reg_info)
         return Error("register %" PRIu32 " not found", reg_index);
 
-    NativeProcessProtocolSP process_sp(m_thread.GetProcess());
-    if (!process_sp)
-        return Error("NativeProcessProtocol is NULL");
-
-    NativeProcessLinux* process_p = static_cast<NativeProcessLinux*>(process_sp.get());
-    return process_p->DoOperation([&] {
-        return DoReadRegisterValue(reg_info->byte_offset, reg_info->name, reg_info->byte_size, reg_value);
-    });
+    return DoReadRegisterValue(reg_info->byte_offset, reg_info->name, reg_info->byte_size, reg_value);
 }
 
 Error
@@ -108,111 +101,70 @@ NativeRegisterContextLinux::WriteRegiste
         }
     }
 
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return Error("NativeProcessProtocol is NULL");
-
     const RegisterInfo *const register_to_write_info_p = GetRegisterInfoAtIndex (reg_to_write);
     assert (register_to_write_info_p && "register to write does not have valid RegisterInfo");
     if (!register_to_write_info_p)
         return Error("NativeRegisterContextLinux::%s failed to get RegisterInfo for write register index %" PRIu32, __FUNCTION__, reg_to_write);
 
-    NativeProcessLinux* process_p = static_cast<NativeProcessLinux*> (process_sp.get ());
-    return process_p->DoOperation([&] {
-        return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, reg_value);
-    });
+    return DoWriteRegisterValue(reg_info->byte_offset, reg_info->name, reg_value);
 }
 
 Error
 NativeRegisterContextLinux::ReadGPR()
 {
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return Error("NativeProcessProtocol is NULL");
-
     void* buf = GetGPRBuffer();
     if (!buf)
         return Error("GPR buffer is NULL");
     size_t buf_size = GetGPRSize();
 
-    NativeProcessLinux* process_p = static_cast<NativeProcessLinux*>(process_sp.get());
-    return process_p->DoOperation([&] { return DoReadGPR(buf, buf_size); });
+    return DoReadGPR(buf, buf_size);
 }
 
 Error
 NativeRegisterContextLinux::WriteGPR()
 {
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return Error("NativeProcessProtocol is NULL");
-
     void* buf = GetGPRBuffer();
     if (!buf)
         return Error("GPR buffer is NULL");
     size_t buf_size = GetGPRSize();
 
-    NativeProcessLinux* process_p = static_cast<NativeProcessLinux*>(process_sp.get());
-    return process_p->DoOperation([&] { return DoWriteGPR(buf, buf_size); });
+    return DoWriteGPR(buf, buf_size);
 }
 
 Error
 NativeRegisterContextLinux::ReadFPR()
 {
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return Error("NativeProcessProtocol is NULL");
-
     void* buf = GetFPRBuffer();
     if (!buf)
         return Error("GPR buffer is NULL");
     size_t buf_size = GetFPRSize();
 
-    NativeProcessLinux* process_p = static_cast<NativeProcessLinux*>(process_sp.get());
-    return process_p->DoOperation([&] { return DoReadFPR(buf, buf_size); });
+    return DoReadFPR(buf, buf_size);
 }
 
 Error
 NativeRegisterContextLinux::WriteFPR()
 {
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    if (!process_sp)
-        return Error("NativeProcessProtocol is NULL");
-
     void* buf = GetFPRBuffer();
     if (!buf)
         return Error("GPR buffer is NULL");
     size_t buf_size = GetFPRSize();
 
-    NativeProcessLinux* process_p = static_cast<NativeProcessLinux*>(process_sp.get());
-    return process_p->DoOperation([&] { return DoWriteFPR(buf, buf_size); });
+    return DoWriteFPR(buf, buf_size);
 }
 
 Error
 NativeRegisterContextLinux::ReadRegisterSet(void *buf, size_t buf_size, unsigned int regset)
 {
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess());
-    if (!process_sp)
-        return Error("NativeProcessProtocol is NULL");
-    NativeProcessLinux* process_p = static_cast<NativeProcessLinux*>(process_sp.get());
-
-    return process_p->DoOperation([&] {
-        return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(),
-                static_cast<void *>(&regset), buf, buf_size);
-    });
+    return NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, m_thread.GetID(),
+            static_cast<void *>(&regset), buf, buf_size);
 }
 
 Error
 NativeRegisterContextLinux::WriteRegisterSet(void *buf, size_t buf_size, unsigned int regset)
 {
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess());
-    if (!process_sp)
-        return Error("NativeProcessProtocol is NULL");
-    NativeProcessLinux* process_p = static_cast<NativeProcessLinux*>(process_sp.get());
-
-    return process_p->DoOperation([&] {
-        return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
-                static_cast<void *>(&regset), buf, buf_size);
-    });
+    return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(),
+            static_cast<void *>(&regset), buf, buf_size);
 }
 
 Error

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp?rev=242783&r1=242782&r2=242783&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp Tue Jul 21 08:20:32 2015
@@ -715,29 +715,23 @@ Error
 NativeRegisterContextLinux_arm64::ReadHardwareDebugInfo(unsigned int &watch_count,
                                                         unsigned int &break_count)
 {
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess());
-    if (!process_sp)
-        return Error("NativeProcessProtocol is NULL");
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*>(process_sp.get());
     ::pid_t tid = m_thread.GetID();
 
-    return process_p->DoOperation([&] {
-        int regset = NT_ARM_HW_WATCH;
-        struct iovec ioVec;
-        struct user_hwdebug_state dreg_state;
-        Error error;
-
-        ioVec.iov_base = &dreg_state;
-        ioVec.iov_len = sizeof (dreg_state);
-        error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset, &ioVec, ioVec.iov_len);
-        watch_count = dreg_state.dbg_info & 0xff;
-
-        regset = NT_ARM_HW_BREAK;
-        error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset, &ioVec, ioVec.iov_len);
-        break_count = dreg_state.dbg_info & 0xff;
+    int regset = NT_ARM_HW_WATCH;
+    struct iovec ioVec;
+    struct user_hwdebug_state dreg_state;
+    Error error;
+
+    ioVec.iov_base = &dreg_state;
+    ioVec.iov_len = sizeof (dreg_state);
+    error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset, &ioVec, ioVec.iov_len);
+    watch_count = dreg_state.dbg_info & 0xff;
+
+    regset = NT_ARM_HW_BREAK;
+    error = NativeProcessLinux::PtraceWrapper(PTRACE_GETREGSET, tid, &regset, &ioVec, ioVec.iov_len);
+    break_count = dreg_state.dbg_info & 0xff;
 
-        return error;
-    });
+    return error;
 }
 
 Error
@@ -746,33 +740,26 @@ NativeRegisterContextLinux_arm64::WriteH
                                                          int type,
                                                          int count)
 {
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess());
-    if (!process_sp)
-        return Error("NativeProcessProtocol is NULL");
-    NativeProcessLinux *const process_p = reinterpret_cast<NativeProcessLinux*>(process_sp.get());
-
-    return process_p->DoOperation([&] {
-        struct iovec ioVec;
-        struct user_hwdebug_state dreg_state;
-        Error error;
-
-        memset (&dreg_state, 0, sizeof (dreg_state));
-        ioVec.iov_base = &dreg_state;
-        ioVec.iov_len = sizeof (dreg_state);
-
-        if (type == 0)
-            type = NT_ARM_HW_WATCH;
-        else
-            type = NT_ARM_HW_BREAK;
-
-        for (int i = 0; i < count; i++)
-        {
-            dreg_state.dbg_regs[i].addr = addr_buf[i];
-            dreg_state.dbg_regs[i].ctrl = cntrl_buf[i];
-        }
+    struct iovec ioVec;
+    struct user_hwdebug_state dreg_state;
+    Error error;
+
+    memset (&dreg_state, 0, sizeof (dreg_state));
+    ioVec.iov_base = &dreg_state;
+    ioVec.iov_len = sizeof (dreg_state);
+
+    if (type == 0)
+        type = NT_ARM_HW_WATCH;
+    else
+        type = NT_ARM_HW_BREAK;
+
+    for (int i = 0; i < count; i++)
+    {
+        dreg_state.dbg_regs[i].addr = addr_buf[i];
+        dreg_state.dbg_regs[i].ctrl = cntrl_buf[i];
+    }
 
-        return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), &type, &ioVec, ioVec.iov_len);
-    });
+    return NativeProcessLinux::PtraceWrapper(PTRACE_SETREGSET, m_thread.GetID(), &type, &ioVec, ioVec.iov_len);
 }
 
 Error

Modified: lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp?rev=242783&r1=242782&r2=242783&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp Tue Jul 21 08:20:32 2015
@@ -877,19 +877,13 @@ NativeRegisterContextLinux_mips64::IsWat
 
     // reading the current state of watch regs
     struct pt_watch_regs watch_readback;
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    NativeProcessLinux *const process_p = static_cast<NativeProcessLinux*> (process_sp.get ());
-    Error error = process_p->DoOperation([&] {
-        return DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&watch_readback));
-    });
+    Error error =  DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&watch_readback));
 
     if (GetWatchHi (&watch_readback, wp_index) & (IRW))
     {
         // clear hit flag in watchhi 
         SetWatchHi (&watch_readback, wp_index, (GetWatchHi (&watch_readback, wp_index) & ~(IRW)));
-        process_p->DoOperation([&] {
-            return DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&watch_readback));
-        });
+        DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&watch_readback));
      
         is_hit = true;
         return error;
@@ -930,11 +924,7 @@ NativeRegisterContextLinux_mips64::Clear
 
     struct pt_watch_regs regs;
     // First reading the current state of watch regs
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    NativeProcessLinux *const process_p = static_cast<NativeProcessLinux*> (process_sp.get ());
-    process_p->DoOperation([&] {
-        return DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void*>(&regs));
-    });
+    DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void*>(&regs));
 
     if (regs.style == pt_watch_style_mips32)
     {
@@ -949,9 +939,7 @@ NativeRegisterContextLinux_mips64::Clear
         regs.mips64.watch_masks[wp_index] = default_watch_regs.mips64.watch_masks[wp_index];
     }
 
-    Error error = process_p->DoOperation([&] {
-        return DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
-    });
+    Error error = DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
     if(!error.Fail())
     {
         hw_addr_map[wp_index] = LLDB_INVALID_ADDRESS;
@@ -963,11 +951,7 @@ NativeRegisterContextLinux_mips64::Clear
 Error
 NativeRegisterContextLinux_mips64::ClearAllHardwareWatchpoints()
 {
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    NativeProcessLinux *const process_p = static_cast<NativeProcessLinux *> (process_sp.get ());
-    return process_p->DoOperation([&] {
-        return DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&default_watch_regs));
-    });
+    return DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&default_watch_regs));
 }
 
 Error
@@ -986,11 +970,7 @@ NativeRegisterContextLinux_mips64::SetHa
     struct pt_watch_regs regs;
 
     // First reading the current state of watch regs
-    NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-    NativeProcessLinux *const process_p = static_cast<NativeProcessLinux*> (process_sp.get ());
-    process_p->DoOperation([&] {
-        return DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
-    });
+    DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
 
     // Try if a new watch point fits in this state
     int index = GetVacantWatchIndex (&regs, addr, size, watch_flags, NumSupportedHardwareWatchpoints());
@@ -1001,9 +981,7 @@ NativeRegisterContextLinux_mips64::SetHa
 
 
     // It fits, so we go ahead with updating the state of watch regs 
-    process_p->DoOperation([&] {
-        return DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
-    });
+    DoWriteWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
 
     // Storing exact address  
     hw_addr_map[index] = addr; 
@@ -1027,17 +1005,7 @@ NativeRegisterContextLinux_mips64::NumSu
     static int num_valid = 0;
     if (!num_valid)
     {
-        NativeProcessProtocolSP process_sp (m_thread.GetProcess ());
-        if (!process_sp)
-        {
-            printf ("NativeProcessProtocol is NULL");
-            return 0;
-        }
-
-        NativeProcessLinux *const process_p = static_cast<NativeProcessLinux*> (process_sp.get ());
-        process_p->DoOperation([&] {
-            return DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
-        });
+        DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast<void *>(&regs));
         default_watch_regs = regs; // Keeping default watch regs values for future use
         switch (regs.style)
         {

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp?rev=242783&r1=242782&r2=242783&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp Tue Jul 21 08:20:32 2015
@@ -97,20 +97,6 @@ GDBRemoteCommunicationServerLLGS::GDBRem
     RegisterPacketHandlers();
 }
 
-//----------------------------------------------------------------------
-// Destructor
-//----------------------------------------------------------------------
-GDBRemoteCommunicationServerLLGS::~GDBRemoteCommunicationServerLLGS()
-{
-    Mutex::Locker locker (m_debugged_process_mutex);
-
-    if (m_debugged_process_sp)
-    {
-        m_debugged_process_sp->Terminate ();
-        m_debugged_process_sp.reset ();
-    }
-}
-
 void
 GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers()
 {
@@ -226,6 +212,7 @@ GDBRemoteCommunicationServerLLGS::Launch
         error = NativeProcessProtocol::Launch(
             m_process_launch_info,
             *this,
+            m_mainloop,
             m_debugged_process_sp);
     }
 
@@ -311,7 +298,7 @@ GDBRemoteCommunicationServerLLGS::Attach
         }
 
         // Try to attach.
-        error = NativeProcessProtocol::Attach(pid, *this, m_debugged_process_sp);
+        error = NativeProcessProtocol::Attach(pid, *this, m_mainloop, m_debugged_process_sp);
         if (!error.Success ())
         {
             fprintf (stderr, "%s: failed to attach to process %" PRIu64 ": %s", __FUNCTION__, pid, error.AsCString ());

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h?rev=242783&r1=242782&r2=242783&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h Tue Jul 21 08:20:32 2015
@@ -42,9 +42,6 @@ public:
     //------------------------------------------------------------------
     GDBRemoteCommunicationServerLLGS(const lldb::PlatformSP& platform_sp, MainLoop &mainloop);
 
-    virtual
-    ~GDBRemoteCommunicationServerLLGS();
-
     //------------------------------------------------------------------
     /// Specify the program to launch and its arguments.
     ///





More information about the lldb-commits mailing list