1af245d11STodd Fiala //===-- NativeProcessLinux.h ---------------------------------- -*- C++ -*-===// 2af245d11STodd Fiala // 3af245d11STodd Fiala // The LLVM Compiler Infrastructure 4af245d11STodd Fiala // 5af245d11STodd Fiala // This file is distributed under the University of Illinois Open Source 6af245d11STodd Fiala // License. See LICENSE.TXT for details. 7af245d11STodd Fiala // 8af245d11STodd Fiala //===----------------------------------------------------------------------===// 9af245d11STodd Fiala 10af245d11STodd Fiala #ifndef liblldb_NativeProcessLinux_H_ 11af245d11STodd Fiala #define liblldb_NativeProcessLinux_H_ 12af245d11STodd Fiala 13af245d11STodd Fiala // C Includes 14af245d11STodd Fiala #include <semaphore.h> 15af245d11STodd Fiala #include <signal.h> 16af245d11STodd Fiala 17af245d11STodd Fiala // C++ Includes 18af245d11STodd Fiala #include <unordered_set> 19af245d11STodd Fiala 20af245d11STodd Fiala // Other libraries and framework includes 21af245d11STodd Fiala #include "lldb/Core/ArchSpec.h" 22af245d11STodd Fiala #include "lldb/lldb-types.h" 23af245d11STodd Fiala #include "lldb/Host/Debug.h" 2439de3110SZachary Turner #include "lldb/Host/HostThread.h" 25af245d11STodd Fiala #include "lldb/Host/Mutex.h" 26af245d11STodd Fiala #include "lldb/Target/MemoryRegionInfo.h" 27af245d11STodd Fiala 282fe1d0abSChaoren Lin #include "lldb/Host/common/NativeProcessProtocol.h" 29af245d11STodd Fiala 30db264a6dSTamas Berghammer namespace lldb_private { 31af245d11STodd Fiala class Error; 32af245d11STodd Fiala class Module; 33af245d11STodd Fiala class Scalar; 34af245d11STodd Fiala 35db264a6dSTamas Berghammer namespace process_linux { 36db264a6dSTamas Berghammer class ThreadStateCoordinator; 37db264a6dSTamas Berghammer 38af245d11STodd Fiala /// @class NativeProcessLinux 39af245d11STodd Fiala /// @brief Manages communication with the inferior (debugee) process. 40af245d11STodd Fiala /// 41af245d11STodd Fiala /// Upon construction, this class prepares and launches an inferior process for 42af245d11STodd Fiala /// debugging. 43af245d11STodd Fiala /// 44af245d11STodd Fiala /// Changes in the inferior process state are broadcasted. 45af245d11STodd Fiala class NativeProcessLinux: public NativeProcessProtocol 46af245d11STodd Fiala { 47af245d11STodd Fiala public: 48af245d11STodd Fiala 49db264a6dSTamas Berghammer static Error 50af245d11STodd Fiala LaunchProcess ( 51af245d11STodd Fiala Module *exe_module, 52af245d11STodd Fiala ProcessLaunchInfo &launch_info, 53db264a6dSTamas Berghammer NativeProcessProtocol::NativeDelegate &native_delegate, 54af245d11STodd Fiala NativeProcessProtocolSP &native_process_sp); 55af245d11STodd Fiala 56db264a6dSTamas Berghammer static Error 57af245d11STodd Fiala AttachToProcess ( 58af245d11STodd Fiala lldb::pid_t pid, 59db264a6dSTamas Berghammer NativeProcessProtocol::NativeDelegate &native_delegate, 60af245d11STodd Fiala NativeProcessProtocolSP &native_process_sp); 61af245d11STodd Fiala 62af245d11STodd Fiala // --------------------------------------------------------------------- 63af245d11STodd Fiala // NativeProcessProtocol Interface 64af245d11STodd Fiala // --------------------------------------------------------------------- 65af245d11STodd Fiala Error 66af245d11STodd Fiala Resume (const ResumeActionList &resume_actions) override; 67af245d11STodd Fiala 68af245d11STodd Fiala Error 69af245d11STodd Fiala Halt () override; 70af245d11STodd Fiala 71af245d11STodd Fiala Error 72af245d11STodd Fiala Detach () override; 73af245d11STodd Fiala 74af245d11STodd Fiala Error 75af245d11STodd Fiala Signal (int signo) override; 76af245d11STodd Fiala 77af245d11STodd Fiala Error 78e9547b80SChaoren Lin Interrupt () override; 79e9547b80SChaoren Lin 80e9547b80SChaoren Lin Error 81af245d11STodd Fiala Kill () override; 82af245d11STodd Fiala 83af245d11STodd Fiala Error 84af245d11STodd Fiala GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &range_info) override; 85af245d11STodd Fiala 86af245d11STodd Fiala Error 87*3eb4b458SChaoren Lin ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override; 88af245d11STodd Fiala 89af245d11STodd Fiala Error 90*3eb4b458SChaoren Lin ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override; 91af245d11STodd Fiala 92af245d11STodd Fiala Error 93*3eb4b458SChaoren Lin WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) override; 94*3eb4b458SChaoren Lin 95*3eb4b458SChaoren Lin Error 96*3eb4b458SChaoren Lin AllocateMemory(size_t size, uint32_t permissions, lldb::addr_t &addr) override; 97af245d11STodd Fiala 98af245d11STodd Fiala Error 99af245d11STodd Fiala DeallocateMemory (lldb::addr_t addr) override; 100af245d11STodd Fiala 101af245d11STodd Fiala lldb::addr_t 102af245d11STodd Fiala GetSharedLibraryInfoAddress () override; 103af245d11STodd Fiala 104af245d11STodd Fiala size_t 105af245d11STodd Fiala UpdateThreads () override; 106af245d11STodd Fiala 107af245d11STodd Fiala bool 108af245d11STodd Fiala GetArchitecture (ArchSpec &arch) const override; 109af245d11STodd Fiala 110af245d11STodd Fiala Error 111af245d11STodd Fiala SetBreakpoint (lldb::addr_t addr, uint32_t size, bool hardware) override; 112af245d11STodd Fiala 113af245d11STodd Fiala void 114af245d11STodd Fiala DoStopIDBumped (uint32_t newBumpId) override; 115af245d11STodd Fiala 1168bc34f4dSOleksiy Vyalov void 1178bc34f4dSOleksiy Vyalov Terminate () override; 1188bc34f4dSOleksiy Vyalov 119af245d11STodd Fiala // --------------------------------------------------------------------- 120af245d11STodd Fiala // Interface used by NativeRegisterContext-derived classes. 121af245d11STodd Fiala // --------------------------------------------------------------------- 122af245d11STodd Fiala 123af245d11STodd Fiala /// Reads the contents from the register identified by the given (architecture 124af245d11STodd Fiala /// dependent) offset. 125af245d11STodd Fiala /// 126af245d11STodd Fiala /// This method is provided for use by RegisterContextLinux derivatives. 12797ccc294SChaoren Lin Error 128af245d11STodd Fiala ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name, 129db264a6dSTamas Berghammer unsigned size, RegisterValue &value); 130af245d11STodd Fiala 131af245d11STodd Fiala /// Writes the given value to the register identified by the given 132af245d11STodd Fiala /// (architecture dependent) offset. 133af245d11STodd Fiala /// 134af245d11STodd Fiala /// This method is provided for use by RegisterContextLinux derivatives. 13597ccc294SChaoren Lin Error 136af245d11STodd Fiala WriteRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name, 137db264a6dSTamas Berghammer const RegisterValue &value); 138af245d11STodd Fiala 139af245d11STodd Fiala /// Reads all general purpose registers into the specified buffer. 14097ccc294SChaoren Lin Error 141af245d11STodd Fiala ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size); 142af245d11STodd Fiala 143af245d11STodd Fiala /// Reads generic floating point registers into the specified buffer. 14497ccc294SChaoren Lin Error 145af245d11STodd Fiala ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size); 146af245d11STodd Fiala 147af245d11STodd Fiala /// Reads the specified register set into the specified buffer. 148af245d11STodd Fiala /// For instance, the extended floating-point register set. 14997ccc294SChaoren Lin Error 150af245d11STodd Fiala ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset); 151af245d11STodd Fiala 152af245d11STodd Fiala /// Writes all general purpose registers into the specified buffer. 15397ccc294SChaoren Lin Error 154af245d11STodd Fiala WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size); 155af245d11STodd Fiala 156af245d11STodd Fiala /// Writes generic floating point registers into the specified buffer. 15797ccc294SChaoren Lin Error 158af245d11STodd Fiala WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size); 159af245d11STodd Fiala 160af245d11STodd Fiala /// Writes the specified register set into the specified buffer. 161af245d11STodd Fiala /// For instance, the extended floating-point register set. 16297ccc294SChaoren Lin Error 163af245d11STodd Fiala WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset); 164af245d11STodd Fiala 1657cb18bf5STamas Berghammer Error 1667cb18bf5STamas Berghammer GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec) override; 1677cb18bf5STamas Berghammer 168af245d11STodd Fiala protected: 169af245d11STodd Fiala // --------------------------------------------------------------------- 170af245d11STodd Fiala // NativeProcessProtocol protected interface 171af245d11STodd Fiala // --------------------------------------------------------------------- 172af245d11STodd Fiala Error 173af245d11STodd Fiala GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hint, size_t &actual_opcode_size, const uint8_t *&trap_opcode_bytes) override; 174af245d11STodd Fiala 175af245d11STodd Fiala private: 176af245d11STodd Fiala 1771107b5a5SPavel Labath class Monitor; 1781107b5a5SPavel Labath 179db264a6dSTamas Berghammer ArchSpec m_arch; 180af245d11STodd Fiala 1811107b5a5SPavel Labath std::unique_ptr<Monitor> m_monitor_up; 182af245d11STodd Fiala 183db264a6dSTamas Berghammer LazyBool m_supports_mem_region; 184af245d11STodd Fiala std::vector<MemoryRegionInfo> m_mem_region_cache; 185db264a6dSTamas Berghammer Mutex m_mem_region_cache_mutex; 186af245d11STodd Fiala 187fa03ad2eSChaoren Lin std::unique_ptr<ThreadStateCoordinator> m_coordinator_up; 188fa03ad2eSChaoren Lin HostThread m_coordinator_thread; 189af245d11STodd Fiala 190d8c338d4STamas Berghammer // List of thread ids stepping with a breakpoint with the address of 191d8c338d4STamas Berghammer // the relevan breakpoint 192d8c338d4STamas Berghammer std::map<lldb::tid_t, lldb::addr_t> m_threads_stepping_with_breakpoint; 193d8c338d4STamas Berghammer 194af245d11STodd Fiala /// @class LauchArgs 195af245d11STodd Fiala /// 196af245d11STodd Fiala /// @brief Simple structure to pass data to the thread responsible for 197af245d11STodd Fiala /// launching a child process. 198bd7cbc5aSPavel Labath struct LaunchArgs 199af245d11STodd Fiala { 200bd7cbc5aSPavel Labath LaunchArgs(Module *module, 201af245d11STodd Fiala char const **argv, 202af245d11STodd Fiala char const **envp, 20375f47c3aSTodd Fiala const std::string &stdin_path, 20475f47c3aSTodd Fiala const std::string &stdout_path, 20575f47c3aSTodd Fiala const std::string &stderr_path, 2060bce1b67STodd Fiala const char *working_dir, 207db264a6dSTamas Berghammer const ProcessLaunchInfo &launch_info); 208af245d11STodd Fiala 209af245d11STodd Fiala ~LaunchArgs(); 210af245d11STodd Fiala 211db264a6dSTamas Berghammer Module *m_module; // The executable image to launch. 212af245d11STodd Fiala char const **m_argv; // Process arguments. 213af245d11STodd Fiala char const **m_envp; // Process environment. 21475f47c3aSTodd Fiala const std::string &m_stdin_path; // Redirect stdin if not empty. 21575f47c3aSTodd Fiala const std::string &m_stdout_path; // Redirect stdout if not empty. 21675f47c3aSTodd Fiala const std::string &m_stderr_path; // Redirect stderr if not empty. 217af245d11STodd Fiala const char *m_working_dir; // Working directory or NULL. 218db264a6dSTamas Berghammer const ProcessLaunchInfo &m_launch_info; 219af245d11STodd Fiala }; 220af245d11STodd Fiala 221bd7cbc5aSPavel Labath typedef std::function<::pid_t(Error &)> InitialOperation; 222af245d11STodd Fiala 223af245d11STodd Fiala // --------------------------------------------------------------------- 224af245d11STodd Fiala // Private Instance Methods 225af245d11STodd Fiala // --------------------------------------------------------------------- 226af245d11STodd Fiala NativeProcessLinux (); 227af245d11STodd Fiala 228af245d11STodd Fiala /// Launches an inferior process ready for debugging. Forms the 229af245d11STodd Fiala /// implementation of Process::DoLaunch. 230af245d11STodd Fiala void 231af245d11STodd Fiala LaunchInferior ( 232af245d11STodd Fiala Module *module, 233af245d11STodd Fiala char const *argv[], 234af245d11STodd Fiala char const *envp[], 23575f47c3aSTodd Fiala const std::string &stdin_path, 23675f47c3aSTodd Fiala const std::string &stdout_path, 23775f47c3aSTodd Fiala const std::string &stderr_path, 238af245d11STodd Fiala const char *working_dir, 239db264a6dSTamas Berghammer const ProcessLaunchInfo &launch_info, 240af245d11STodd Fiala Error &error); 241af245d11STodd Fiala 242af245d11STodd Fiala /// Attaches to an existing process. Forms the 2430cbf0b13STamas Berghammer /// implementation of Process::DoAttach 244af245d11STodd Fiala void 245af245d11STodd Fiala AttachToInferior (lldb::pid_t pid, Error &error); 246af245d11STodd Fiala 247af245d11STodd Fiala void 248bd7cbc5aSPavel Labath StartMonitorThread(const InitialOperation &operation, Error &error); 2491107b5a5SPavel Labath 250bd7cbc5aSPavel Labath ::pid_t 251bd7cbc5aSPavel Labath Launch(LaunchArgs *args, Error &error); 252af245d11STodd Fiala 253bd7cbc5aSPavel Labath ::pid_t 254bd7cbc5aSPavel Labath Attach(lldb::pid_t pid, Error &error); 255af245d11STodd Fiala 25697ccc294SChaoren Lin static Error 257af245d11STodd Fiala SetDefaultPtraceOpts(const lldb::pid_t); 258af245d11STodd Fiala 259af245d11STodd Fiala static bool 260af245d11STodd Fiala DupDescriptor(const char *path, int fd, int flags); 261af245d11STodd Fiala 2621107b5a5SPavel Labath static void * 2631107b5a5SPavel Labath MonitorThread(void *baton); 2641107b5a5SPavel Labath 2651107b5a5SPavel Labath void 2661107b5a5SPavel Labath MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status); 267af245d11STodd Fiala 268af245d11STodd Fiala void 269426bdf88SPavel Labath WaitForNewThread(::pid_t tid); 270426bdf88SPavel Labath 271426bdf88SPavel Labath void 272af245d11STodd Fiala MonitorSIGTRAP(const siginfo_t *info, lldb::pid_t pid); 273af245d11STodd Fiala 274af245d11STodd Fiala void 275c16f5dcaSChaoren Lin MonitorTrace(lldb::pid_t pid, NativeThreadProtocolSP thread_sp); 276c16f5dcaSChaoren Lin 277c16f5dcaSChaoren Lin void 278c16f5dcaSChaoren Lin MonitorBreakpoint(lldb::pid_t pid, NativeThreadProtocolSP thread_sp); 279c16f5dcaSChaoren Lin 280c16f5dcaSChaoren Lin void 281c16f5dcaSChaoren Lin MonitorWatchpoint(lldb::pid_t pid, NativeThreadProtocolSP thread_sp, uint32_t wp_index); 282c16f5dcaSChaoren Lin 283c16f5dcaSChaoren Lin void 284af245d11STodd Fiala MonitorSignal(const siginfo_t *info, lldb::pid_t pid, bool exited); 285af245d11STodd Fiala 286e7708688STamas Berghammer bool 287e7708688STamas Berghammer SupportHardwareSingleStepping() const; 288e7708688STamas Berghammer 289e7708688STamas Berghammer Error 290e7708688STamas Berghammer SetupSoftwareSingleStepping(NativeThreadProtocolSP thread_sp); 291e7708688STamas Berghammer 292af245d11STodd Fiala #if 0 293af245d11STodd Fiala static ::ProcessMessage::CrashReason 294af245d11STodd Fiala GetCrashReasonForSIGSEGV(const siginfo_t *info); 295af245d11STodd Fiala 296af245d11STodd Fiala static ::ProcessMessage::CrashReason 297af245d11STodd Fiala GetCrashReasonForSIGILL(const siginfo_t *info); 298af245d11STodd Fiala 299af245d11STodd Fiala static ::ProcessMessage::CrashReason 300af245d11STodd Fiala GetCrashReasonForSIGFPE(const siginfo_t *info); 301af245d11STodd Fiala 302af245d11STodd Fiala static ::ProcessMessage::CrashReason 303af245d11STodd Fiala GetCrashReasonForSIGBUS(const siginfo_t *info); 304af245d11STodd Fiala #endif 305af245d11STodd Fiala 306fa03ad2eSChaoren Lin Error 307fa03ad2eSChaoren Lin StartCoordinatorThread (); 308fa03ad2eSChaoren Lin 309fa03ad2eSChaoren Lin static void* 310fa03ad2eSChaoren Lin CoordinatorThread (void *arg); 311fa03ad2eSChaoren Lin 312fa03ad2eSChaoren Lin void 313fa03ad2eSChaoren Lin StopCoordinatorThread (); 314fa03ad2eSChaoren Lin 315af245d11STodd Fiala /// Stops monitoring the child process thread. 316af245d11STodd Fiala void 317af245d11STodd Fiala StopMonitor(); 318af245d11STodd Fiala 319af245d11STodd Fiala bool 320af245d11STodd Fiala HasThreadNoLock (lldb::tid_t thread_id); 321af245d11STodd Fiala 322af245d11STodd Fiala NativeThreadProtocolSP 323af245d11STodd Fiala MaybeGetThreadNoLock (lldb::tid_t thread_id); 324af245d11STodd Fiala 325af245d11STodd Fiala bool 326af245d11STodd Fiala StopTrackingThread (lldb::tid_t thread_id); 327af245d11STodd Fiala 328af245d11STodd Fiala NativeThreadProtocolSP 329af245d11STodd Fiala AddThread (lldb::tid_t thread_id); 330af245d11STodd Fiala 331af245d11STodd Fiala Error 33263c8be95STamas Berghammer GetSoftwareBreakpointPCOffset (NativeRegisterContextSP context_sp, uint32_t &actual_opcode_size); 333af245d11STodd Fiala 334af245d11STodd Fiala Error 335af245d11STodd Fiala FixupBreakpointPCAsNeeded (NativeThreadProtocolSP &thread_sp); 336af245d11STodd Fiala 337af245d11STodd Fiala /// Writes a siginfo_t structure corresponding to the given thread ID to the 338af245d11STodd Fiala /// memory region pointed to by @p siginfo. 33997ccc294SChaoren Lin Error 34097ccc294SChaoren Lin GetSignalInfo(lldb::tid_t tid, void *siginfo); 341af245d11STodd Fiala 342af245d11STodd Fiala /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG) 343af245d11STodd Fiala /// corresponding to the given thread ID to the memory pointed to by @p 344af245d11STodd Fiala /// message. 34597ccc294SChaoren Lin Error 346af245d11STodd Fiala GetEventMessage(lldb::tid_t tid, unsigned long *message); 347af245d11STodd Fiala 348af245d11STodd Fiala /// Resumes the given thread. If @p signo is anything but 349af245d11STodd Fiala /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread. 35097ccc294SChaoren Lin Error 351af245d11STodd Fiala Resume(lldb::tid_t tid, uint32_t signo); 352af245d11STodd Fiala 353af245d11STodd Fiala /// Single steps the given thread. If @p signo is anything but 354af245d11STodd Fiala /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread. 35597ccc294SChaoren Lin Error 356af245d11STodd Fiala SingleStep(lldb::tid_t tid, uint32_t signo); 357af245d11STodd Fiala 358fa03ad2eSChaoren Lin // ThreadStateCoordinator helper methods. 359511e5cdcSTodd Fiala void 360fa03ad2eSChaoren Lin NotifyThreadCreateStopped (lldb::tid_t tid); 361511e5cdcSTodd Fiala 362511e5cdcSTodd Fiala void 363fa03ad2eSChaoren Lin NotifyThreadCreateRunning (lldb::tid_t tid); 364fa03ad2eSChaoren Lin 365fa03ad2eSChaoren Lin void 366fa03ad2eSChaoren Lin NotifyThreadDeath (lldb::tid_t tid); 367fa03ad2eSChaoren Lin 368fa03ad2eSChaoren Lin void 369fa03ad2eSChaoren Lin NotifyThreadStop (lldb::tid_t tid); 370fa03ad2eSChaoren Lin 371fa03ad2eSChaoren Lin void 372fa03ad2eSChaoren Lin CallAfterRunningThreadsStop (lldb::tid_t tid, 373fa03ad2eSChaoren Lin const std::function<void (lldb::tid_t tid)> &call_after_function); 374511e5cdcSTodd Fiala 37503f12d6bSChaoren Lin void 37603f12d6bSChaoren Lin CallAfterRunningThreadsStopWithSkipTID (lldb::tid_t deferred_signal_tid, 37703f12d6bSChaoren Lin lldb::tid_t skip_stop_request_tid, 37803f12d6bSChaoren Lin const std::function<void (lldb::tid_t tid)> &call_after_function); 37903f12d6bSChaoren Lin 380db264a6dSTamas Berghammer Error 381af245d11STodd Fiala Detach(lldb::tid_t tid); 38286fd8e45SChaoren Lin 383db264a6dSTamas Berghammer Error 38486fd8e45SChaoren Lin RequestThreadStop (const lldb::pid_t pid, const lldb::tid_t tid); 385af245d11STodd Fiala }; 386db264a6dSTamas Berghammer 387db264a6dSTamas Berghammer } // namespace process_linux 388db264a6dSTamas Berghammer } // namespace lldb_private 389af245d11STodd Fiala 390af245d11STodd Fiala #endif // #ifndef liblldb_NativeProcessLinux_H_ 391