From: Russell Harmon <eatnumb...@google.com> --- source/Plugins/Process/Linux/CMakeLists.txt | 2 + source/Plugins/Process/Linux/ProcessMonitor.cpp | 16 ++ source/Plugins/Process/Linux/ProcessMonitor.h | 25 +-- .../Plugins/Process/Linux/ProcessMonitorOther.cpp | 6 +- source/Plugins/Process/Linux/ProcessMonitorOther.h | 2 - .../Plugins/Process/Linux/ProcessMonitorSelf.cpp | 237 +++++++++++++++++++++ source/Plugins/Process/Linux/ProcessMonitorSelf.h | 164 ++++++++++++++ source/Plugins/Process/POSIX/ProcessPOSIX.cpp | 9 +- 8 files changed, 439 insertions(+), 22 deletions(-) create mode 100644 source/Plugins/Process/Linux/ProcessMonitor.cpp create mode 100644 source/Plugins/Process/Linux/ProcessMonitorSelf.cpp create mode 100644 source/Plugins/Process/Linux/ProcessMonitorSelf.h
diff --git a/source/Plugins/Process/Linux/CMakeLists.txt b/source/Plugins/Process/Linux/CMakeLists.txt index 9b04315..021828e 100644 --- a/source/Plugins/Process/Linux/CMakeLists.txt +++ b/source/Plugins/Process/Linux/CMakeLists.txt @@ -9,7 +9,9 @@ add_lldb_library(lldbPluginProcessLinux NativeRegisterContextLinux_x86_64.cpp NativeThreadLinux.cpp ProcessLinux.cpp + ProcessMonitor.cpp ProcessMonitorOther.cpp + ProcessMonitorSelf.cpp ProcFileReader.cpp LinuxThread.cpp ) diff --git a/source/Plugins/Process/Linux/ProcessMonitor.cpp b/source/Plugins/Process/Linux/ProcessMonitor.cpp new file mode 100644 index 0000000..780d20a --- /dev/null +++ b/source/Plugins/Process/Linux/ProcessMonitor.cpp @@ -0,0 +1,16 @@ +//===-- ProcessMonitor.cpp ------------------------------------ -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ProcessPOSIX.h" +#include "ProcessLinux.h" +#include "ProcessMonitor.h" + +ProcessMonitor::ProcessMonitor(ProcessPOSIX *process) + : m_process(static_cast<ProcessLinux *>(process)) +{} diff --git a/source/Plugins/Process/Linux/ProcessMonitor.h b/source/Plugins/Process/Linux/ProcessMonitor.h index 96ddf28..1c3c9d3 100644 --- a/source/Plugins/Process/Linux/ProcessMonitor.h +++ b/source/Plugins/Process/Linux/ProcessMonitor.h @@ -22,12 +22,9 @@ namespace lldb_private { class Error; -class Module; -class Scalar; } // End lldb_private namespace. class ProcessLinux; -class Operation; /// @class ProcessMonitor /// @brief Manages communication with the inferior (debugee) process. @@ -44,12 +41,18 @@ class Operation; class ProcessMonitor { public: - virtual ~ProcessMonitor() {}; + ProcessMonitor(ProcessPOSIX *process); + + virtual ~ProcessMonitor() {} /// Provides the process number of debugee. virtual lldb::pid_t GetPID() const = 0; + /// Returns the process associated with this ProcessMonitorOther. + ProcessLinux & + GetProcess() { return *m_process; } + /// Returns a file descriptor to the controlling terminal of the inferior /// process. /// @@ -125,17 +128,6 @@ public: virtual bool ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value) = 0; - /// Writes a siginfo_t structure corresponding to the given thread ID to the - /// memory region pointed to by @p siginfo. - virtual bool - GetSignalInfo(lldb::tid_t tid, void *siginfo, int &ptrace_err) = 0; - - /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG) - /// corresponding to the given thread IDto the memory pointed to by @p - /// message. - virtual bool - GetEventMessage(lldb::tid_t tid, unsigned long *message) = 0; - /// Resumes the given thread. If @p signo is anything but /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread. virtual bool @@ -164,6 +156,9 @@ public: // Waits for the initial stop message from a new thread. virtual bool WaitForInitialTIDStop(lldb::tid_t tid) = 0; + +protected: + ProcessLinux *m_process; }; #endif // #ifndef liblldb_ProcessMonitor_H_ diff --git a/source/Plugins/Process/Linux/ProcessMonitorOther.cpp b/source/Plugins/Process/Linux/ProcessMonitorOther.cpp index 6ba900d..d151663 100644 --- a/source/Plugins/Process/Linux/ProcessMonitorOther.cpp +++ b/source/Plugins/Process/Linux/ProcessMonitorOther.cpp @@ -1008,8 +1008,7 @@ ProcessMonitorOther::ProcessMonitorOther(ProcessPOSIX *process, const char *stderr_path, const char *working_dir, lldb_private::Error &error) - : ProcessMonitor(), - m_process(static_cast<ProcessLinux *>(process)), + : ProcessMonitor(process), m_operation_thread(LLDB_INVALID_HOST_THREAD), m_monitor_thread(LLDB_INVALID_HOST_THREAD), m_pid(LLDB_INVALID_PROCESS_ID), @@ -1062,8 +1061,7 @@ WAIT_AGAIN: ProcessMonitorOther::ProcessMonitorOther(ProcessPOSIX *process, lldb::pid_t pid, lldb_private::Error &error) - : ProcessMonitor(), - m_process(static_cast<ProcessLinux *>(process)), + : ProcessMonitor(process), m_operation_thread(LLDB_INVALID_HOST_THREAD), m_monitor_thread(LLDB_INVALID_HOST_THREAD), m_pid(LLDB_INVALID_PROCESS_ID), diff --git a/source/Plugins/Process/Linux/ProcessMonitorOther.h b/source/Plugins/Process/Linux/ProcessMonitorOther.h index 7a61cc2..d5dc087 100644 --- a/source/Plugins/Process/Linux/ProcessMonitorOther.h +++ b/source/Plugins/Process/Linux/ProcessMonitorOther.h @@ -194,8 +194,6 @@ public: WaitForInitialTIDStop(lldb::tid_t tid); private: - ProcessLinux *m_process; - lldb::thread_t m_operation_thread; lldb::thread_t m_monitor_thread; lldb::pid_t m_pid; diff --git a/source/Plugins/Process/Linux/ProcessMonitorSelf.cpp b/source/Plugins/Process/Linux/ProcessMonitorSelf.cpp new file mode 100644 index 0000000..79e2833 --- /dev/null +++ b/source/Plugins/Process/Linux/ProcessMonitorSelf.cpp @@ -0,0 +1,237 @@ +//===-- ProcessMonitorSelf.cpp ------------------------------------ -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/lldb-python.h" + +// C Includes +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include <stdlib.h> +#include <stddef.h> + +// C++ Includes +// Self libraries and framework includes +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Error.h" +#include "lldb/Core/RegisterValue.h" +#include "lldb/Core/Scalar.h" +#include "lldb/Host/Host.h" +#include "lldb/Target/Thread.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Utility/PseudoTerminal.h" + +#include "POSIXThread.h" +#include "ProcessLinux.h" +#include "ProcessPOSIXLog.h" +#include "ProcessMonitorSelf.h" + +using namespace lldb_private; + +ProcessMonitorSelf::ProcessMonitorSelf(ProcessPOSIX *process, + lldb_private::Error &error) + : ProcessMonitor(process), + m_terminal_fd(-1) +{ + // TODO: Determine a better size for this buffer + // TODO: Do something reasonable if stderr is not open on the same terminal + // as stdout. + char buf[1024]; + int err = ttyname_r(STDOUT_FILENO, buf, 1024); + if (err != 0) { + // TODO: Handle the error + assert(false); + } + + int fd = open(buf, O_RDONLY); + if (fd == -1) { + // TODO: Handle the error + assert(false); + } + + m_terminal_fd = fd; + + process->SendMessage(ProcessMessage::Attach(GetPID())); +} + +ProcessMonitorSelf::~ProcessMonitorSelf() { + // TODO: Handle errors on close + close(m_terminal_fd); +} + +/// Provides the process number of debugee. +lldb::pid_t +ProcessMonitorSelf::GetPID() const +{ + return getpid(); +} + +/// Returns a file descriptor to the controlling terminal of the inferior +/// process. +/// +/// Reads from this file descriptor yield both the standard output and +/// standard error of this debugee. Even if stderr and stdout were +/// redirected on launch it may still happen that data is available on this +/// descriptor (if the inferior process opens /dev/tty, for example). +/// +/// If this monitor was attached to an existing process this method returns +/// -1. +int +ProcessMonitorSelf::GetTerminalFD() const { + return m_terminal_fd; +} + +/// Reads @p size bytes from address @vm_adder in the inferior process +/// address space. +/// +/// This method is provided to implement Process::DoReadMemory. +size_t +ProcessMonitorSelf::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, + lldb_private::Error &error) +{ + memcpy(buf, (void *) vm_addr, size); + return size; +} + +/// Writes @p size bytes from address @p vm_adder in the inferior process +/// address space. +/// +/// This method is provided to implement Process::DoWriteMemory. +size_t +ProcessMonitorSelf::WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, + lldb_private::Error &error) +{ + memcpy((void *) vm_addr, buf, size); + return size; +} + +/// Reads the contents from the register identified by the given (architecture +/// dependent) offset. +/// +/// This method is provided for use by RegisterContextLinux derivatives. +bool +ProcessMonitorSelf::ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name, + unsigned size, lldb_private::RegisterValue &value) +{ + assert(false); +} + +/// Writes the given value to the register identified by the given +/// (architecture dependent) offset. +/// +/// This method is provided for use by RegisterContextLinux derivatives. +bool +ProcessMonitorSelf::WriteRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name, + const lldb_private::RegisterValue &value) +{ + assert(false); +} + +/// Reads all general purpose registers into the specified buffer. +bool +ProcessMonitorSelf::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size) +{ + assert(false); +} + +/// Reads generic floating point registers into the specified buffer. +bool +ProcessMonitorSelf::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size) +{ + assert(false); +} + +/// Reads the specified register set into the specified buffer. +/// For instance, the extended floating-point register set. +bool +ProcessMonitorSelf::ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset) +{ + assert(false); +} + +/// Writes all general purpose registers into the specified buffer. +bool +ProcessMonitorSelf::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size) +{ + assert(false); +} + +/// Writes generic floating point registers into the specified buffer. +bool +ProcessMonitorSelf::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size) +{ + assert(false); +} + +/// Writes the specified register set into the specified buffer. +/// For instance, the extended floating-point register set. +bool +ProcessMonitorSelf::WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset) +{ + assert(false); +} + +/// Reads the value of the thread-specific pointer for a given thread ID. +bool +ProcessMonitorSelf::ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value) +{ + assert(false); +} + +/// Resumes the given thread. If @p signo is anything but +/// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread. +bool +ProcessMonitorSelf::Resume(lldb::tid_t tid, uint32_t signo) +{ + assert(false); +} + +/// Single steps the given thread. If @p signo is anything but +/// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread. +bool +ProcessMonitorSelf::SingleStep(lldb::tid_t tid, uint32_t signo) +{ + assert(false); +} + +/// Terminate the traced process. +bool +ProcessMonitorSelf::Kill() +{ + exit(EXIT_SUCCESS); +} + +lldb_private::Error +ProcessMonitorSelf::Detach(lldb::tid_t tid) +{ + return Error(); +} + +/// Stops the monitoring the child process thread. +void +ProcessMonitorSelf::StopMonitor() +{} + +/// Stops the requested thread and waits for the stop signal. +bool +ProcessMonitorSelf::StopThread(lldb::tid_t tid) +{ + assert(false); +} + +// Waits for the initial stop message from a new thread. +bool +ProcessMonitorSelf::WaitForInitialTIDStop(lldb::tid_t tid) +{ + assert(false); +} diff --git a/source/Plugins/Process/Linux/ProcessMonitorSelf.h b/source/Plugins/Process/Linux/ProcessMonitorSelf.h new file mode 100644 index 0000000..4b4a4e4 --- /dev/null +++ b/source/Plugins/Process/Linux/ProcessMonitorSelf.h @@ -0,0 +1,164 @@ +//===-- ProcessMonitorSelf.h -------------------------------------- -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ProcessMonitorSelf_H_ +#define liblldb_ProcessMonitorSelf_H_ + +// C Includes +#include <semaphore.h> +#include <signal.h> + +// C++ Includes +// Self libraries and framework includes +#include "lldb/lldb-types.h" +#include "lldb/Host/Mutex.h" + +#include "ProcessMonitor.h" + +namespace lldb_private +{ +class Error; +class Module; +class Scalar; +} // End lldb_private namespace. + +class ProcessLinux; +class Operation; + +/// @class ProcessMonitorSelf +/// @brief Manages communication with the inferior (debugee) process. +/// +/// Upon construction, this class prepares and launches an inferior process for +/// debugging. +/// +/// Changes in the inferior process state are propagated to the associated +/// ProcessLinux instance by calling ProcessLinux::SendMessage with the +/// appropriate ProcessMessage events. +/// +/// A purposely minimal set of operations are provided to interrogate and change +/// the inferior process state. +class ProcessMonitorSelf : public ProcessMonitor +{ +public: + ProcessMonitorSelf(ProcessPOSIX *process, lldb_private::Error &error); + ~ProcessMonitorSelf(); + + /// Provides the process number of debugee. + lldb::pid_t + GetPID() const; + + /// Returns a file descriptor to the controlling terminal of the inferior + /// process. + /// + /// Reads from this file descriptor yield both the standard output and + /// standard error of this debugee. Even if stderr and stdout were + /// redirected on launch it may still happen that data is available on this + /// descriptor (if the inferior process opens /dev/tty, for example). + /// + /// If this monitor was attached to an existing process this method returns + /// -1. + int + GetTerminalFD() const; + + /// Reads @p size bytes from address @vm_adder in the inferior process + /// address space. + /// + /// This method is provided to implement Process::DoReadMemory. + size_t + ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, + lldb_private::Error &error); + + /// Writes @p size bytes from address @p vm_adder in the inferior process + /// address space. + /// + /// This method is provided to implement Process::DoWriteMemory. + size_t + WriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, + lldb_private::Error &error); + + /// Reads the contents from the register identified by the given (architecture + /// dependent) offset. + /// + /// This method is provided for use by RegisterContextLinux derivatives. + bool + ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name, + unsigned size, lldb_private::RegisterValue &value); + + /// Writes the given value to the register identified by the given + /// (architecture dependent) offset. + /// + /// This method is provided for use by RegisterContextLinux derivatives. + bool + WriteRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name, + const lldb_private::RegisterValue &value); + + /// Reads all general purpose registers into the specified buffer. + bool + ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size); + + /// Reads generic floating point registers into the specified buffer. + bool + ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size); + + /// Reads the specified register set into the specified buffer. + /// For instance, the extended floating-point register set. + bool + ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset); + + /// Writes all general purpose registers into the specified buffer. + bool + WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size); + + /// Writes generic floating point registers into the specified buffer. + bool + WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size); + + /// Writes the specified register set into the specified buffer. + /// For instance, the extended floating-point register set. + bool + WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset); + + /// Reads the value of the thread-specific pointer for a given thread ID. + bool + ReadThreadPointer(lldb::tid_t tid, lldb::addr_t &value); + + /// Resumes the given thread. If @p signo is anything but + /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread. + bool + Resume(lldb::tid_t tid, uint32_t signo); + + /// Single steps the given thread. If @p signo is anything but + /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread. + bool + SingleStep(lldb::tid_t tid, uint32_t signo); + + /// Terminate the traced process. + bool + Kill(); + + lldb_private::Error + Detach(lldb::tid_t tid); + + /// Stops the monitoring the child process thread. + void + StopMonitor(); + + /// Stops the requested thread and waits for the stop signal. + bool + StopThread(lldb::tid_t tid); + + // Waits for the initial stop message from a new thread. + bool + WaitForInitialTIDStop(lldb::tid_t tid); + +private: + int m_terminal_fd; +}; + +#endif // #ifndef liblldb_ProcessMonitorSelf_H_ diff --git a/source/Plugins/Process/POSIX/ProcessPOSIX.cpp b/source/Plugins/Process/POSIX/ProcessPOSIX.cpp index 8333f01..fef629e 100644 --- a/source/Plugins/Process/POSIX/ProcessPOSIX.cpp +++ b/source/Plugins/Process/POSIX/ProcessPOSIX.cpp @@ -11,6 +11,8 @@ // C Includes #include <errno.h> +#include <sys/types.h> +#include <unistd.h> // C++ Includes // Other libraries and framework includes @@ -30,6 +32,7 @@ #include "Plugins/Process/Utility/InferiorCallPOSIX.h" #include "ProcessMonitor.h" #include "ProcessMonitorOther.h" +#include "ProcessMonitorSelf.h" #include "POSIXThread.h" using namespace lldb; @@ -124,7 +127,11 @@ ProcessPOSIX::DoAttachToProcessWithID(lldb::pid_t pid) if (log && log->GetMask().Test(POSIX_LOG_VERBOSE)) log->Printf ("ProcessPOSIX::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID()); - m_monitor = new ProcessMonitorOther(this, pid, error); + if ((::pid_t) pid == getpid()) { + m_monitor = new ProcessMonitorSelf(this, error); + } else { + m_monitor = new ProcessMonitorOther(this, pid, error); + } if (!error.Success()) return error; -- 2.1.0.rc2.206.gedb03e5 _______________________________________________ lldb-dev mailing list lldb-dev@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev