diff options
Diffstat (limited to 'lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp')
-rw-r--r-- | lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp | 319 |
1 files changed, 75 insertions, 244 deletions
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp index ffafbaca21f..e47cb52e8cc 100644 --- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -226,18 +226,17 @@ namespace // 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 @@ namespace 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 @@ namespace 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 @@ namespace { 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 @@ namespace } 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 @@ private: 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 @@ public: void Terminate(); - void - DoOperation(Operation *op); + Error + DoOperation(const Operation &op); class ScopedOperationLock { Monitor &m_monitor; @@ -728,24 +540,23 @@ NativeProcessLinux::Monitor::Initialize() 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 @@ NativeProcessLinux::Monitor::HandleCommands() 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 @@ NativeProcessLinux::ReadMemory (lldb::addr_t addr, void *buf, size_t size, size_ // 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 @@ NativeProcessLinux::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t s 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 @@ NativeProcessLinux::Resume (lldb::tid_t tid, uint32_t signo) 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 @@ NativeProcessLinux::Detach(lldb::tid_t tid) 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 @@ NativeProcessLinux::ThreadWasCreated (lldb::tid_t tid) } 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. |