[NativeProcessLinux] Use lambdas in DoOperation calls

Summary:
This removes a lot of boilerplate, which was needed to execute monitor operations. Previously one
needed do declare a separate class for each operation which would manually capture all needed
arguments, which was very verbose. In addition to less code, I believe this also makes the code
more readable, since now the implementation of the operation can be physically closer to the code
that invokes it.

Test Plan: Code compiles on x86, arm and mips, tests pass on x86 linux.

Reviewers: tberghammer, chaoren

Subscribers: aemerson, lldb-commits

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

llvm-svn: 240772
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index ffafbac..e47cb52 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -226,18 +226,17 @@
     // NativeProcessLinux::WriteMemory.  This enables mutual recursion between these
     // functions without needed to go thru the thread funnel.
 
-    size_t
+    Error
     DoReadMemory(
         lldb::pid_t pid,
         lldb::addr_t vm_addr,
         void *buf,
         size_t size,
-        Error &error)
+        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 bytes_read;
         size_t remainder;
         long data;
 
@@ -251,12 +250,13 @@
         assert(sizeof(data) >= word_size);
         for (bytes_read = 0; bytes_read < size; bytes_read += remainder)
         {
+            Error error;
             data = NativeProcessLinux::PtraceWrapper(PTRACE_PEEKDATA, pid, (void*)vm_addr, nullptr, 0, error);
             if (error.Fail())
             {
                 if (log)
                     ProcessPOSIXLog::DecNestLevel();
-                return bytes_read;
+                return error;
             }
 
             remainder = size - bytes_read;
@@ -284,22 +284,22 @@
 
         if (log)
             ProcessPOSIXLog::DecNestLevel();
-        return bytes_read;
+        return Error();
     }
 
-    size_t
+    Error
     DoWriteMemory(
         lldb::pid_t pid,
         lldb::addr_t vm_addr,
         const void *buf,
         size_t size,
-        Error &error)
+        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 bytes_written = 0;
         size_t remainder;
+        Error error;
 
         Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL));
         if (log)
@@ -331,28 +331,30 @@
                 {
                     if (log)
                         ProcessPOSIXLog::DecNestLevel();
-                    return bytes_written;
+                    return error;
                 }
             }
             else
             {
                 unsigned char buff[8];
-                if (DoReadMemory(pid, vm_addr,
-                                buff, word_size, error) != word_size)
+                size_t bytes_read;
+                error = DoReadMemory(pid, vm_addr, buff, word_size, bytes_read);
+                if (error.Fail())
                 {
                     if (log)
                         ProcessPOSIXLog::DecNestLevel();
-                    return bytes_written;
+                    return error;
                 }
 
                 memcpy(buff, src, remainder);
 
-                if (DoWriteMemory(pid, vm_addr,
-                                buff, word_size, error) != word_size)
+                size_t bytes_written_rec;
+                error = DoWriteMemory(pid, vm_addr, buff, word_size, bytes_written_rec);
+                if (error.Fail())
                 {
                     if (log)
                         ProcessPOSIXLog::DecNestLevel();
-                    return bytes_written;
+                    return error;
                 }
 
                 if (log && ProcessPOSIXLog::AtTopNestLevel() &&
@@ -368,197 +370,7 @@
         }
         if (log)
             ProcessPOSIXLog::DecNestLevel();
-        return bytes_written;
-    }
-
-    //------------------------------------------------------------------------------
-    /// @class ReadOperation
-    /// @brief Implements NativeProcessLinux::ReadMemory.
-    class ReadOperation : public NativeProcessLinux::Operation
-    {
-    public:
-        ReadOperation(
-            lldb::addr_t addr,
-            void *buff,
-            size_t size,
-            size_t &result) :
-            Operation (),
-            m_addr (addr),
-            m_buff (buff),
-            m_size (size),
-            m_result (result)
-            {
-            }
-
-        void Execute (NativeProcessLinux *process) override;
-
-    private:
-        lldb::addr_t m_addr;
-        void *m_buff;
-        size_t m_size;
-        size_t &m_result;
-    };
-
-    void
-    ReadOperation::Execute (NativeProcessLinux *process)
-    {
-        m_result = DoReadMemory (process->GetID (), m_addr, m_buff, m_size, m_error);
-    }
-
-    //------------------------------------------------------------------------------
-    /// @class WriteOperation
-    /// @brief Implements NativeProcessLinux::WriteMemory.
-    class WriteOperation : public NativeProcessLinux::Operation
-    {
-    public:
-        WriteOperation(
-            lldb::addr_t addr,
-            const void *buff,
-            size_t size,
-            size_t &result) :
-            Operation (),
-            m_addr (addr),
-            m_buff (buff),
-            m_size (size),
-            m_result (result)
-            {
-            }
-
-        void Execute (NativeProcessLinux *process) override;
-
-    private:
-        lldb::addr_t m_addr;
-        const void *m_buff;
-        size_t m_size;
-        size_t &m_result;
-    };
-
-    void
-    WriteOperation::Execute(NativeProcessLinux *process)
-    {
-        m_result = DoWriteMemory (process->GetID (), m_addr, m_buff, m_size, m_error);
-    }
-
-    //------------------------------------------------------------------------------
-    /// @class ResumeOperation
-    /// @brief Implements NativeProcessLinux::Resume.
-    class ResumeOperation : public NativeProcessLinux::Operation
-    {
-    public:
-        ResumeOperation(lldb::tid_t tid, uint32_t signo) :
-            m_tid(tid), m_signo(signo) { }
-
-        void Execute(NativeProcessLinux *monitor) override;
-
-    private:
-        lldb::tid_t m_tid;
-        uint32_t m_signo;
-    };
-
-    void
-    ResumeOperation::Execute(NativeProcessLinux *monitor)
-    {
-        intptr_t data = 0;
-
-        if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
-            data = m_signo;
-
-        NativeProcessLinux::PtraceWrapper(PTRACE_CONT, m_tid, nullptr, (void*)data, 0, m_error);
-        if (m_error.Fail())
-        {
-            Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
-
-            if (log)
-                log->Printf ("ResumeOperation (%"  PRIu64 ") failed: %s", m_tid, m_error.AsCString());
-        }
-    }
-
-    //------------------------------------------------------------------------------
-    /// @class SingleStepOperation
-    /// @brief Implements NativeProcessLinux::SingleStep.
-    class SingleStepOperation : public NativeProcessLinux::Operation
-    {
-    public:
-        SingleStepOperation(lldb::tid_t tid, uint32_t signo)
-            : m_tid(tid), m_signo(signo) { }
-
-        void Execute(NativeProcessLinux *monitor) override;
-
-    private:
-        lldb::tid_t m_tid;
-        uint32_t m_signo;
-    };
-
-    void
-    SingleStepOperation::Execute(NativeProcessLinux *monitor)
-    {
-        intptr_t data = 0;
-
-        if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
-            data = m_signo;
-
-        NativeProcessLinux::PtraceWrapper(PTRACE_SINGLESTEP, m_tid, nullptr, (void*)data, 0, m_error);
-    }
-
-    //------------------------------------------------------------------------------
-    /// @class SiginfoOperation
-    /// @brief Implements NativeProcessLinux::GetSignalInfo.
-    class SiginfoOperation : public NativeProcessLinux::Operation
-    {
-    public:
-        SiginfoOperation(lldb::tid_t tid, void *info)
-            : m_tid(tid), m_info(info) { }
-
-        void Execute(NativeProcessLinux *monitor) override;
-
-    private:
-        lldb::tid_t m_tid;
-        void *m_info;
-    };
-
-    void
-    SiginfoOperation::Execute(NativeProcessLinux *monitor)
-    {
-        NativeProcessLinux::PtraceWrapper(PTRACE_GETSIGINFO, m_tid, nullptr, m_info, 0, m_error);
-    }
-
-    //------------------------------------------------------------------------------
-    /// @class EventMessageOperation
-    /// @brief Implements NativeProcessLinux::GetEventMessage.
-    class EventMessageOperation : public NativeProcessLinux::Operation
-    {
-    public:
-        EventMessageOperation(lldb::tid_t tid, unsigned long *message)
-            : m_tid(tid), m_message(message) { }
-
-        void Execute(NativeProcessLinux *monitor) override;
-
-    private:
-        lldb::tid_t m_tid;
-        unsigned long *m_message;
-    };
-
-    void
-    EventMessageOperation::Execute(NativeProcessLinux *monitor)
-    {
-        NativeProcessLinux::PtraceWrapper(PTRACE_GETEVENTMSG, m_tid, nullptr, m_message, 0, m_error);
-    }
-
-    class DetachOperation : public NativeProcessLinux::Operation
-    {
-    public:
-        DetachOperation(lldb::tid_t tid) : m_tid(tid) { }
-
-        void Execute(NativeProcessLinux *monitor) override;
-
-    private:
-        lldb::tid_t m_tid;
-    };
-
-    void
-    DetachOperation::Execute(NativeProcessLinux *monitor)
-    {
-        NativeProcessLinux::PtraceWrapper(PTRACE_DETACH, m_tid, nullptr, 0, 0, m_error);
+        return error;
     }
 } // end of anonymous namespace
 
@@ -610,10 +422,10 @@
     HostThread m_thread;
 
     // current operation which must be executed on the priviliged thread
-    Mutex      m_operation_mutex;
-    Operation *m_operation = nullptr;
-    sem_t      m_operation_sem;
-    Error      m_operation_error;
+    Mutex            m_operation_mutex;
+    const Operation *m_operation = nullptr;
+    sem_t            m_operation_sem;
+    Error            m_operation_error;
 
     unsigned   m_operation_nesting_level = 0;
 
@@ -671,8 +483,8 @@
     void
     Terminate();
 
-    void
-    DoOperation(Operation *op);
+    Error
+    DoOperation(const Operation &op);
 
     class ScopedOperationLock {
         Monitor &m_monitor;
@@ -728,24 +540,23 @@
     return WaitForAck();
 }
 
-void
-NativeProcessLinux::Monitor::DoOperation(Operation *op)
+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.
-        op->Execute(m_native_process);
-        return;
+        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;
+    m_operation = &op;
 
     // notify the thread that an operation is ready to be processed
     write(m_pipefd[WRITE], &operation_command, sizeof operation_command);
 
-    WaitForAck();
+    return WaitForAck();
 }
 
 void
@@ -899,7 +710,7 @@
         switch (command)
         {
         case operation_command:
-            m_operation->Execute(m_native_process);
+            m_operation_error = (*m_operation)();
             break;
         case begin_block_command:
             ++m_operation_nesting_level;
@@ -3329,9 +3140,7 @@
         //     the call failed for some reason, let's retry the read using ptrace api.
     }
 
-    ReadOperation op(addr, buf, size, bytes_read);
-    m_monitor_up->DoOperation(&op);
-    return op.GetError ();
+    return DoOperation([&] { return DoReadMemory(GetID(), addr, buf, size, bytes_read); });
 }
 
 Error
@@ -3345,9 +3154,7 @@
 Error
 NativeProcessLinux::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written)
 {
-    WriteOperation op(addr, buf, size, bytes_written);
-    m_monitor_up->DoOperation(&op);
-    return op.GetError ();
+    return DoOperation([&] { return DoWriteMemory(GetID(), addr, buf, size, bytes_written); });
 }
 
 Error
@@ -3358,35 +3165,58 @@
     if (log)
         log->Printf ("NativeProcessLinux::%s() resuming thread = %"  PRIu64 " with signal %s", __FUNCTION__, tid,
                                  GetUnixSignals().GetSignalAsCString (signo));
-    ResumeOperation op (tid, signo);
-    m_monitor_up->DoOperation (&op);
+
+
+
+    intptr_t data = 0;
+
+    if (signo != LLDB_INVALID_SIGNAL_NUMBER)
+        data = signo;
+
+    Error error = DoOperation([&] {
+        Error error;
+        NativeProcessLinux::PtraceWrapper(PTRACE_CONT, tid, nullptr, (void*)data, 0, error);
+        return error;
+    });
+
     if (log)
-        log->Printf ("NativeProcessLinux::%s() resuming thread = %"  PRIu64 " result = %s", __FUNCTION__, tid, op.GetError().Success() ? "true" : "false");
-    return op.GetError();
+        log->Printf ("NativeProcessLinux::%s() resuming thread = %"  PRIu64 " result = %s", __FUNCTION__, tid, error.Success() ? "true" : "false");
+    return error;
 }
 
 Error
 NativeProcessLinux::SingleStep(lldb::tid_t tid, uint32_t signo)
 {
-    SingleStepOperation op(tid, signo);
-    m_monitor_up->DoOperation(&op);
-    return op.GetError();
+    intptr_t data = 0;
+
+    if (signo != LLDB_INVALID_SIGNAL_NUMBER)
+        data = signo;
+
+    return DoOperation([&] {
+        Error error;
+        NativeProcessLinux::PtraceWrapper(PTRACE_SINGLESTEP, tid, nullptr, (void*)data, 0, error);
+        return error;
+    });
 }
 
 Error
 NativeProcessLinux::GetSignalInfo(lldb::tid_t tid, void *siginfo)
 {
-    SiginfoOperation op(tid, siginfo);
-    m_monitor_up->DoOperation(&op);
-    return op.GetError();
+    return DoOperation([&] {
+        Error error;
+        NativeProcessLinux::PtraceWrapper(PTRACE_GETSIGINFO, tid, nullptr, siginfo, 0, error);
+        return error;
+    });
 }
 
 Error
 NativeProcessLinux::GetEventMessage(lldb::tid_t tid, unsigned long *message)
 {
-    EventMessageOperation op(tid, message);
-    m_monitor_up->DoOperation(&op);
-    return op.GetError();
+    return DoOperation([&] {
+        Error error;
+        NativeProcessLinux::PtraceWrapper(PTRACE_GETEVENTMSG, tid, nullptr, message, 0, error);
+        return error;
+    });
 }
 
 Error
@@ -3395,9 +3225,11 @@
     if (tid == LLDB_INVALID_THREAD_ID)
         return Error();
 
-    DetachOperation op(tid);
-    m_monitor_up->DoOperation(&op);
-    return op.GetError();
+    return DoOperation([&] {
+        Error error;
+        NativeProcessLinux::PtraceWrapper(PTRACE_DETACH, tid, nullptr, 0, 0, error);
+        return error;
+    });
 }
 
 bool
@@ -3893,10 +3725,9 @@
 }
 
 Error
-NativeProcessLinux::DoOperation(Operation* op)
+NativeProcessLinux::DoOperation(const Operation &op)
 {
-    m_monitor_up->DoOperation(op);
-    return op->GetError();
+    return m_monitor_up->DoOperation(op);
 }
 
 // Wrapper for ptrace to catch errors and log calls.