diff options
Diffstat (limited to 'include/lldb/Host')
-rw-r--r-- | include/lldb/Host/Host.h | 4 | ||||
-rw-r--r-- | include/lldb/Host/MainLoop.h | 27 | ||||
-rw-r--r-- | include/lldb/Host/MainLoopBase.h | 94 | ||||
-rw-r--r-- | include/lldb/Host/StringConvert.h | 2 | ||||
-rw-r--r-- | include/lldb/Host/common/NativeProcessProtocol.h | 59 | ||||
-rw-r--r-- | include/lldb/Host/posix/ConnectionFileDescriptorPosix.h | 7 | ||||
-rw-r--r-- | include/lldb/Host/posix/MainLoopPosix.h | 100 |
7 files changed, 282 insertions, 11 deletions
diff --git a/include/lldb/Host/Host.h b/include/lldb/Host/Host.h index caf33634057d..235367a7cc5c 100644 --- a/include/lldb/Host/Host.h +++ b/include/lldb/Host/Host.h @@ -244,8 +244,8 @@ public: #endif // !defined(__ANDROID__) && !defined(__ANDROID_NDK__) #endif // defined (__APPLE__) || defined (__linux__) || defined (__FreeBSD__) || defined (__GLIBC__) || defined(__NetBSD__) - static const lldb_private::UnixSignalsSP& - GetUnixSignals (); + static const lldb::UnixSignalsSP & + GetUnixSignals(); static Error LaunchProcess (ProcessLaunchInfo &launch_info); diff --git a/include/lldb/Host/MainLoop.h b/include/lldb/Host/MainLoop.h new file mode 100644 index 000000000000..276538a336b6 --- /dev/null +++ b/include/lldb/Host/MainLoop.h @@ -0,0 +1,27 @@ +//===-- MainLoop.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_MainLoop_h_ +#define lldb_Host_MainLoop_h_ + +#ifdef _WIN32 +#include "lldb/Host/MainLoopBase.h" +namespace lldb_private +{ +typedef MainLoopBase MainLoop; +} +#else +#include "lldb/Host/posix/MainLoopPosix.h" +namespace lldb_private +{ +typedef MainLoopPosix MainLoop; +} +#endif + +#endif // lldb_Host_MainLoop_h_ diff --git a/include/lldb/Host/MainLoopBase.h b/include/lldb/Host/MainLoopBase.h new file mode 100644 index 000000000000..bff2ce78110d --- /dev/null +++ b/include/lldb/Host/MainLoopBase.h @@ -0,0 +1,94 @@ +//===-- MainLoopBase.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_posix_MainLoopBase_h_ +#define lldb_Host_posix_MainLoopBase_h_ + +#include <functional> + +#include "llvm/Support/ErrorHandling.h" + +#include "lldb/Core/Error.h" +#include "lldb/Host/IOObject.h" + +namespace lldb_private { + +// The purpose of this class is to enable multiplexed processing of data from different sources +// without resorting to multi-threading. Clients can register IOObjects, which will be monitored +// for readability, and when they become ready, the specified callback will be invoked. +// Monitoring for writability is not supported, but can be easily added if needed. +// +// The RegisterReadObject function return a handle, which controls the duration of the monitoring. When +// this handle is destroyed, the callback is deregistered. +// +// This class simply defines the interface common for all platforms, actual implementations are +// platform-specific. +class MainLoopBase +{ +private: + class ReadHandle; + +public: + MainLoopBase() { } + virtual ~MainLoopBase() { } + + typedef std::unique_ptr<ReadHandle> ReadHandleUP; + + typedef std::function<void(MainLoopBase &)> Callback; + + virtual ReadHandleUP + RegisterReadObject(const lldb::IOObjectSP &object_sp, const Callback &callback, Error &error) + { llvm_unreachable("Not implemented"); } + + // Waits for registered events and invoke the proper callbacks. Returns when all callbacks + // deregister themselves or when someone requests termination. + virtual Error + Run() + { llvm_unreachable("Not implemented"); } + + // Requests the exit of the Run() function. + virtual void + RequestTermination() + { llvm_unreachable("Not implemented"); } + +protected: + ReadHandleUP + CreateReadHandle(const lldb::IOObjectSP &object_sp) + { return ReadHandleUP(new ReadHandle(*this, object_sp)); } + + virtual void + UnregisterReadObject(const lldb::IOObjectSP &object_sp) + { llvm_unreachable("Not implemented"); } + +private: + class ReadHandle + { + public: + ~ReadHandle() { m_mainloop.UnregisterReadObject(m_object_sp); } + + private: + ReadHandle(MainLoopBase &mainloop, const lldb::IOObjectSP &object_sp) + : m_mainloop(mainloop), m_object_sp(object_sp) + { } + + MainLoopBase &m_mainloop; + lldb::IOObjectSP m_object_sp; + + friend class MainLoopBase; + DISALLOW_COPY_AND_ASSIGN(ReadHandle); + }; + +private: + DISALLOW_COPY_AND_ASSIGN(MainLoopBase); +}; + +} // namespace lldb_private + + +#endif // lldb_Host_posix_MainLoopBase_h_ diff --git a/include/lldb/Host/StringConvert.h b/include/lldb/Host/StringConvert.h index 3cc260cf2be1..af5c2a08db87 100644 --- a/include/lldb/Host/StringConvert.h +++ b/include/lldb/Host/StringConvert.h @@ -39,6 +39,8 @@ ToSInt64 (const char *s, int64_t fail_value = 0, int base = 0, bool *success_ptr uint64_t ToUInt64 (const char *s, uint64_t fail_value = 0, int base = 0, bool *success_ptr = nullptr); +double +ToDouble (const char *s, double fail_value = 0.0, bool *success_ptr = nullptr); } // namespace StringConvert } // namespace lldb_private diff --git a/include/lldb/Host/common/NativeProcessProtocol.h b/include/lldb/Host/common/NativeProcessProtocol.h index f6a685aae147..4f0f3a962d32 100644 --- a/include/lldb/Host/common/NativeProcessProtocol.h +++ b/include/lldb/Host/common/NativeProcessProtocol.h @@ -35,8 +35,6 @@ namespace lldb_private friend class SoftwareBreakpoint; public: - static NativeProcessProtocol * - CreateInstance (lldb::pid_t pid); // lldb_private::Host calls should be used to launch a process for debugging, and // then the process should be attached to. When attaching to a process @@ -44,7 +42,6 @@ namespace lldb_private // and then this function should be called. NativeProcessProtocol (lldb::pid_t pid); - public: virtual ~NativeProcessProtocol () { } @@ -297,6 +294,62 @@ namespace lldb_private virtual Error GetFileLoadAddress(const llvm::StringRef& file_name, lldb::addr_t& load_addr) = 0; + //------------------------------------------------------------------ + /// Launch a process for debugging. This method will create an concrete + /// instance of NativeProcessProtocol, based on the host platform. + /// (e.g. NativeProcessLinux on linux, etc.) + /// + /// @param[in] launch_info + /// Information required to launch the process. + /// + /// @param[in] native_delegate + /// The delegate that will receive messages regarding the + /// inferior. Must outlive the NativeProcessProtocol + /// instance. + /// + /// @param[out] process_sp + /// On successful return from the method, this parameter + /// contains the shared pointer to the + /// NativeProcessProtocol that can be used to manipulate + /// the native process. + /// + /// @return + /// An error object indicating if the operation succeeded, + /// and if not, what error occurred. + //------------------------------------------------------------------ + static Error + Launch (ProcessLaunchInfo &launch_info, + NativeDelegate &native_delegate, + NativeProcessProtocolSP &process_sp); + + //------------------------------------------------------------------ + /// Attach to an existing process. This method will create an concrete + /// instance of NativeProcessProtocol, based on the host platform. + /// (e.g. NativeProcessLinux on linux, etc.) + /// + /// @param[in] pid + /// pid of the process locatable + /// + /// @param[in] native_delegate + /// The delegate that will receive messages regarding the + /// inferior. Must outlive the NativeProcessProtocol + /// instance. + /// + /// @param[out] process_sp + /// On successful return from the method, this parameter + /// contains the shared pointer to the + /// NativeProcessProtocol that can be used to manipulate + /// the native process. + /// + /// @return + /// An error object indicating if the operation succeeded, + /// and if not, what error occurred. + //------------------------------------------------------------------ + static Error + Attach (lldb::pid_t pid, + NativeDelegate &native_delegate, + NativeProcessProtocolSP &process_sp); + protected: lldb::pid_t m_pid; diff --git a/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h b/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h index bcbb6014b116..2e0fd705b2a8 100644 --- a/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h +++ b/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h @@ -59,12 +59,7 @@ class ConnectionFileDescriptor : public Connection bool InterruptRead() override; lldb::IOObjectSP - GetReadObject() - { - return m_read_sp; - } - const lldb::IOObjectSP - GetReadObject() const + GetReadObject() override { return m_read_sp; } diff --git a/include/lldb/Host/posix/MainLoopPosix.h b/include/lldb/Host/posix/MainLoopPosix.h new file mode 100644 index 000000000000..9a665ded295e --- /dev/null +++ b/include/lldb/Host/posix/MainLoopPosix.h @@ -0,0 +1,100 @@ +//===-- MainLoopPosix.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_Host_posix_MainLoopPosix_h_ +#define lldb_Host_posix_MainLoopPosix_h_ + +#include "lldb/Host/MainLoopBase.h" + +#include "llvm/ADT/DenseMap.h" + +namespace lldb_private { + +// Posix implementation of the MainLoopBase class. It can monitor file descriptors for +// readability using pselect. In addition to the common base, this class provides the ability to +// invoke a given handler when a signal is received. +// +// Since this class is primarily intended to be used for single-threaded processing, it does not +// attempt to perform any internal synchronisation and any concurrent accesses must be protected +// externally. However, it is perfectly legitimate to have more than one instance of this class +// running on separate threads, or even a single thread (with some limitations on signal +// monitoring). +// TODO: Add locking if this class is to be used in a multi-threaded context. +class MainLoopPosix: public MainLoopBase +{ +private: + class SignalHandle; + +public: + typedef std::unique_ptr<SignalHandle> SignalHandleUP; + + ~MainLoopPosix() override; + + ReadHandleUP + RegisterReadObject(const lldb::IOObjectSP &object_sp, const Callback &callback, Error &error) override; + + // Listening for signals from multiple MainLoopPosix instances is perfectly safe as long as they + // don't try to listen for the same signal. The callback function is invoked when the control + // returns to the Run() function, not when the hander is executed. This means that you can + // treat the callback as a normal function and perform things which would not be safe in a + // signal handler. However, since the callback is not invoked synchronously, you cannot use + // this mechanism to handle SIGSEGV and the like. + SignalHandleUP + RegisterSignal(int signo, const Callback &callback, Error &error); + + Error + Run() override; + + // This should only be performed from a callback. Do not attempt to terminate the processing + // from another thread. + // TODO: Add synchronization if we want to be terminated from another thread. + void + RequestTermination() override + { m_terminate_request = true; } + +protected: + void + UnregisterReadObject(const lldb::IOObjectSP &object_sp) override; + + void + UnregisterSignal(int signo); + +private: + class SignalHandle + { + public: + ~SignalHandle() { m_mainloop.UnregisterSignal(m_signo); } + + private: + SignalHandle(MainLoopPosix &mainloop, int signo) : m_mainloop(mainloop), m_signo(signo) { } + + MainLoopPosix &m_mainloop; + int m_signo; + + friend class MainLoopPosix; + DISALLOW_COPY_AND_ASSIGN(SignalHandle); + }; + + struct SignalInfo + { + Callback callback; + struct sigaction old_action; + bool was_blocked : 1; + }; + + llvm::DenseMap<IOObject::WaitableHandle, Callback> m_read_fds; + llvm::DenseMap<int, SignalInfo> m_signals; + bool m_terminate_request : 1; +}; + +} // namespace lldb_private + + +#endif // lldb_Host_posix_MainLoopPosix_h_ + |