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 <unordered_set> 15af245d11STodd Fiala 16af245d11STodd Fiala // Other libraries and framework includes 17af245d11STodd Fiala #include "lldb/Core/ArchSpec.h" 18af245d11STodd Fiala #include "lldb/lldb-types.h" 19af245d11STodd Fiala #include "lldb/Host/Debug.h" 20d3173f34SChaoren Lin #include "lldb/Host/FileSpec.h" 2139de3110SZachary Turner #include "lldb/Host/HostThread.h" 22af245d11STodd Fiala #include "lldb/Host/Mutex.h" 23af245d11STodd Fiala #include "lldb/Target/MemoryRegionInfo.h" 24af245d11STodd Fiala 252fe1d0abSChaoren Lin #include "lldb/Host/common/NativeProcessProtocol.h" 268c8ff7afSPavel Labath #include "NativeThreadLinux.h" 27af245d11STodd Fiala 28db264a6dSTamas Berghammer namespace lldb_private { 29af245d11STodd Fiala class Error; 30af245d11STodd Fiala class Module; 31af245d11STodd Fiala class Scalar; 32af245d11STodd Fiala 33db264a6dSTamas Berghammer namespace process_linux { 34af245d11STodd Fiala /// @class NativeProcessLinux 35af245d11STodd Fiala /// @brief Manages communication with the inferior (debugee) process. 36af245d11STodd Fiala /// 37af245d11STodd Fiala /// Upon construction, this class prepares and launches an inferior process for 38af245d11STodd Fiala /// debugging. 39af245d11STodd Fiala /// 40af245d11STodd Fiala /// Changes in the inferior process state are broadcasted. 41af245d11STodd Fiala class NativeProcessLinux: public NativeProcessProtocol 42af245d11STodd Fiala { 43d5b310f2SPavel Labath friend Error 44d5b310f2SPavel Labath NativeProcessProtocol::Launch (ProcessLaunchInfo &launch_info, 45d5b310f2SPavel Labath NativeDelegate &native_delegate, 4619cbe96aSPavel Labath MainLoop &mainloop, 47d5b310f2SPavel Labath NativeProcessProtocolSP &process_sp); 48d5b310f2SPavel Labath 49d5b310f2SPavel Labath friend Error 50d5b310f2SPavel Labath NativeProcessProtocol::Attach (lldb::pid_t pid, 51d5b310f2SPavel Labath NativeProcessProtocol::NativeDelegate &native_delegate, 5219cbe96aSPavel Labath MainLoop &mainloop, 5319cbe96aSPavel Labath NativeProcessProtocolSP &process_sp); 54d5b310f2SPavel Labath 55c307c270SSean Callanan public: 56af245d11STodd Fiala // --------------------------------------------------------------------- 57af245d11STodd Fiala // NativeProcessProtocol Interface 58af245d11STodd Fiala // --------------------------------------------------------------------- 59af245d11STodd Fiala Error 60af245d11STodd Fiala Resume (const ResumeActionList &resume_actions) override; 61af245d11STodd Fiala 62af245d11STodd Fiala Error 63af245d11STodd Fiala Halt () override; 64af245d11STodd Fiala 65af245d11STodd Fiala Error 66af245d11STodd Fiala Detach () override; 67af245d11STodd Fiala 68af245d11STodd Fiala Error 69af245d11STodd Fiala Signal (int signo) override; 70af245d11STodd Fiala 71af245d11STodd Fiala Error 72e9547b80SChaoren Lin Interrupt () override; 73e9547b80SChaoren Lin 74e9547b80SChaoren Lin Error 75af245d11STodd Fiala Kill () override; 76af245d11STodd Fiala 77af245d11STodd Fiala Error 78af245d11STodd Fiala GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &range_info) override; 79af245d11STodd Fiala 80af245d11STodd Fiala Error 813eb4b458SChaoren Lin ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override; 82af245d11STodd Fiala 83af245d11STodd Fiala Error 843eb4b458SChaoren Lin ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override; 85af245d11STodd Fiala 86af245d11STodd Fiala Error 873eb4b458SChaoren Lin WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) override; 883eb4b458SChaoren Lin 893eb4b458SChaoren Lin Error 903eb4b458SChaoren Lin AllocateMemory(size_t size, uint32_t permissions, lldb::addr_t &addr) override; 91af245d11STodd Fiala 92af245d11STodd Fiala Error 93af245d11STodd Fiala DeallocateMemory (lldb::addr_t addr) override; 94af245d11STodd Fiala 95af245d11STodd Fiala lldb::addr_t 96af245d11STodd Fiala GetSharedLibraryInfoAddress () override; 97af245d11STodd Fiala 98af245d11STodd Fiala size_t 99af245d11STodd Fiala UpdateThreads () override; 100af245d11STodd Fiala 101af245d11STodd Fiala bool 102af245d11STodd Fiala GetArchitecture (ArchSpec &arch) const override; 103af245d11STodd Fiala 104af245d11STodd Fiala Error 105af245d11STodd Fiala SetBreakpoint (lldb::addr_t addr, uint32_t size, bool hardware) override; 106af245d11STodd Fiala 107af245d11STodd Fiala void 108af245d11STodd Fiala DoStopIDBumped (uint32_t newBumpId) override; 109af245d11STodd Fiala 110068f8a7eSTamas Berghammer Error 111068f8a7eSTamas Berghammer GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec) override; 112068f8a7eSTamas Berghammer 113783bfc8cSTamas Berghammer Error 114783bfc8cSTamas Berghammer GetFileLoadAddress(const llvm::StringRef& file_name, lldb::addr_t& load_addr) override; 115783bfc8cSTamas Berghammer 116*f9077782SPavel Labath NativeThreadLinuxSP 117*f9077782SPavel Labath GetThreadByID(lldb::tid_t id); 118*f9077782SPavel Labath 119af245d11STodd Fiala // --------------------------------------------------------------------- 120af245d11STodd Fiala // Interface used by NativeRegisterContext-derived classes. 121af245d11STodd Fiala // --------------------------------------------------------------------- 1224a9babb2SPavel Labath static Error 1234a9babb2SPavel Labath PtraceWrapper(int req, 1244a9babb2SPavel Labath lldb::pid_t pid, 1254a9babb2SPavel Labath void *addr = nullptr, 1264a9babb2SPavel Labath void *data = nullptr, 1274a9babb2SPavel Labath size_t data_size = 0, 1284a9babb2SPavel Labath long *result = nullptr); 1297cb18bf5STamas Berghammer 130af245d11STodd Fiala protected: 131af245d11STodd Fiala // --------------------------------------------------------------------- 132af245d11STodd Fiala // NativeProcessProtocol protected interface 133af245d11STodd Fiala // --------------------------------------------------------------------- 134af245d11STodd Fiala Error 135af245d11STodd Fiala GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hint, size_t &actual_opcode_size, const uint8_t *&trap_opcode_bytes) override; 136af245d11STodd Fiala 137af245d11STodd Fiala private: 138af245d11STodd Fiala 13919cbe96aSPavel Labath MainLoop::SignalHandleUP m_sigchld_handle; 140db264a6dSTamas Berghammer ArchSpec m_arch; 141af245d11STodd Fiala 142db264a6dSTamas Berghammer LazyBool m_supports_mem_region; 143af245d11STodd Fiala std::vector<MemoryRegionInfo> m_mem_region_cache; 144db264a6dSTamas Berghammer Mutex m_mem_region_cache_mutex; 145af245d11STodd Fiala 1460e1d729bSPavel Labath lldb::tid_t m_pending_notification_tid; 1470e1d729bSPavel Labath 148d8c338d4STamas Berghammer // List of thread ids stepping with a breakpoint with the address of 149d8c338d4STamas Berghammer // the relevan breakpoint 150d8c338d4STamas Berghammer std::map<lldb::tid_t, lldb::addr_t> m_threads_stepping_with_breakpoint; 151d8c338d4STamas Berghammer 152af245d11STodd Fiala /// @class LauchArgs 153af245d11STodd Fiala /// 154af245d11STodd Fiala /// @brief Simple structure to pass data to the thread responsible for 155af245d11STodd Fiala /// launching a child process. 156bd7cbc5aSPavel Labath struct LaunchArgs 157af245d11STodd Fiala { 158bd7cbc5aSPavel Labath LaunchArgs(Module *module, 159af245d11STodd Fiala char const **argv, 160af245d11STodd Fiala char const **envp, 161d3173f34SChaoren Lin const FileSpec &stdin_file_spec, 162d3173f34SChaoren Lin const FileSpec &stdout_file_spec, 163d3173f34SChaoren Lin const FileSpec &stderr_file_spec, 164d3173f34SChaoren Lin const FileSpec &working_dir, 165db264a6dSTamas Berghammer const ProcessLaunchInfo &launch_info); 166af245d11STodd Fiala 167af245d11STodd Fiala ~LaunchArgs(); 168af245d11STodd Fiala 169db264a6dSTamas Berghammer Module *m_module; // The executable image to launch. 170af245d11STodd Fiala char const **m_argv; // Process arguments. 171af245d11STodd Fiala char const **m_envp; // Process environment. 172d3173f34SChaoren Lin const FileSpec m_stdin_file_spec; // Redirect stdin if not empty. 173d3173f34SChaoren Lin const FileSpec m_stdout_file_spec; // Redirect stdout if not empty. 174d3173f34SChaoren Lin const FileSpec m_stderr_file_spec; // Redirect stderr if not empty. 175d3173f34SChaoren Lin const FileSpec m_working_dir; // Working directory or empty. 176db264a6dSTamas Berghammer const ProcessLaunchInfo &m_launch_info; 177af245d11STodd Fiala }; 178af245d11STodd Fiala 179bd7cbc5aSPavel Labath typedef std::function< ::pid_t(Error &)> InitialOperation; 180af245d11STodd Fiala 181af245d11STodd Fiala // --------------------------------------------------------------------- 182af245d11STodd Fiala // Private Instance Methods 183af245d11STodd Fiala // --------------------------------------------------------------------- 184af245d11STodd Fiala NativeProcessLinux (); 185af245d11STodd Fiala 186af245d11STodd Fiala /// Launches an inferior process ready for debugging. Forms the 187af245d11STodd Fiala /// implementation of Process::DoLaunch. 188af245d11STodd Fiala void 189af245d11STodd Fiala LaunchInferior ( 19019cbe96aSPavel Labath MainLoop &mainloop, 191af245d11STodd Fiala Module *module, 192af245d11STodd Fiala char const *argv[], 193af245d11STodd Fiala char const *envp[], 194d3173f34SChaoren Lin const FileSpec &stdin_file_spec, 195d3173f34SChaoren Lin const FileSpec &stdout_file_spec, 196d3173f34SChaoren Lin const FileSpec &stderr_file_spec, 197d3173f34SChaoren Lin const FileSpec &working_dir, 198db264a6dSTamas Berghammer const ProcessLaunchInfo &launch_info, 199af245d11STodd Fiala Error &error); 200af245d11STodd Fiala 201af245d11STodd Fiala /// Attaches to an existing process. Forms the 2020cbf0b13STamas Berghammer /// implementation of Process::DoAttach 203af245d11STodd Fiala void 20419cbe96aSPavel Labath AttachToInferior (MainLoop &mainloop, lldb::pid_t pid, Error &error); 2051107b5a5SPavel Labath 206bd7cbc5aSPavel Labath ::pid_t 207bd7cbc5aSPavel Labath Launch(LaunchArgs *args, Error &error); 208af245d11STodd Fiala 209bd7cbc5aSPavel Labath ::pid_t 210bd7cbc5aSPavel Labath Attach(lldb::pid_t pid, Error &error); 211af245d11STodd Fiala 21297ccc294SChaoren Lin static Error 213af245d11STodd Fiala SetDefaultPtraceOpts(const lldb::pid_t); 214af245d11STodd Fiala 215af245d11STodd Fiala static bool 216d3173f34SChaoren Lin DupDescriptor(const FileSpec &file_spec, int fd, int flags); 217af245d11STodd Fiala 2181107b5a5SPavel Labath static void * 2191107b5a5SPavel Labath MonitorThread(void *baton); 2201107b5a5SPavel Labath 2211107b5a5SPavel Labath void 2221107b5a5SPavel Labath MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status); 223af245d11STodd Fiala 224af245d11STodd Fiala void 225426bdf88SPavel Labath WaitForNewThread(::pid_t tid); 226426bdf88SPavel Labath 227426bdf88SPavel Labath void 228af245d11STodd Fiala MonitorSIGTRAP(const siginfo_t *info, lldb::pid_t pid); 229af245d11STodd Fiala 230af245d11STodd Fiala void 231*f9077782SPavel Labath MonitorTrace(lldb::pid_t pid, const NativeThreadLinuxSP &thread_sp); 232c16f5dcaSChaoren Lin 233c16f5dcaSChaoren Lin void 234*f9077782SPavel Labath MonitorBreakpoint(lldb::pid_t pid, const NativeThreadLinuxSP &thread_sp); 235c16f5dcaSChaoren Lin 236c16f5dcaSChaoren Lin void 237*f9077782SPavel Labath MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index); 238c16f5dcaSChaoren Lin 239c16f5dcaSChaoren Lin void 240af245d11STodd Fiala MonitorSignal(const siginfo_t *info, lldb::pid_t pid, bool exited); 241af245d11STodd Fiala 242e7708688STamas Berghammer bool 243e7708688STamas Berghammer SupportHardwareSingleStepping() const; 244e7708688STamas Berghammer 245e7708688STamas Berghammer Error 246e7708688STamas Berghammer SetupSoftwareSingleStepping(NativeThreadProtocolSP thread_sp); 247e7708688STamas Berghammer 248af245d11STodd Fiala #if 0 249af245d11STodd Fiala static ::ProcessMessage::CrashReason 250af245d11STodd Fiala GetCrashReasonForSIGSEGV(const siginfo_t *info); 251af245d11STodd Fiala 252af245d11STodd Fiala static ::ProcessMessage::CrashReason 253af245d11STodd Fiala GetCrashReasonForSIGILL(const siginfo_t *info); 254af245d11STodd Fiala 255af245d11STodd Fiala static ::ProcessMessage::CrashReason 256af245d11STodd Fiala GetCrashReasonForSIGFPE(const siginfo_t *info); 257af245d11STodd Fiala 258af245d11STodd Fiala static ::ProcessMessage::CrashReason 259af245d11STodd Fiala GetCrashReasonForSIGBUS(const siginfo_t *info); 260af245d11STodd Fiala #endif 261af245d11STodd Fiala 262af245d11STodd Fiala bool 263af245d11STodd Fiala HasThreadNoLock (lldb::tid_t thread_id); 264af245d11STodd Fiala 265af245d11STodd Fiala NativeThreadProtocolSP 266af245d11STodd Fiala MaybeGetThreadNoLock (lldb::tid_t thread_id); 267af245d11STodd Fiala 268af245d11STodd Fiala bool 269af245d11STodd Fiala StopTrackingThread (lldb::tid_t thread_id); 270af245d11STodd Fiala 271*f9077782SPavel Labath NativeThreadLinuxSP 272af245d11STodd Fiala AddThread (lldb::tid_t thread_id); 273af245d11STodd Fiala 274af245d11STodd Fiala Error 27563c8be95STamas Berghammer GetSoftwareBreakpointPCOffset (NativeRegisterContextSP context_sp, uint32_t &actual_opcode_size); 276af245d11STodd Fiala 277af245d11STodd Fiala Error 278*f9077782SPavel Labath FixupBreakpointPCAsNeeded(const NativeThreadLinuxSP &thread_sp); 279af245d11STodd Fiala 280af245d11STodd Fiala /// Writes a siginfo_t structure corresponding to the given thread ID to the 281af245d11STodd Fiala /// memory region pointed to by @p siginfo. 28297ccc294SChaoren Lin Error 28397ccc294SChaoren Lin GetSignalInfo(lldb::tid_t tid, void *siginfo); 284af245d11STodd Fiala 285af245d11STodd Fiala /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG) 286af245d11STodd Fiala /// corresponding to the given thread ID to the memory pointed to by @p 287af245d11STodd Fiala /// message. 28897ccc294SChaoren Lin Error 289af245d11STodd Fiala GetEventMessage(lldb::tid_t tid, unsigned long *message); 290af245d11STodd Fiala 291af245d11STodd Fiala /// Resumes the given thread. If @p signo is anything but 292af245d11STodd Fiala /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread. 29397ccc294SChaoren Lin Error 294af245d11STodd Fiala Resume(lldb::tid_t tid, uint32_t signo); 295af245d11STodd Fiala 296af245d11STodd Fiala /// Single steps the given thread. If @p signo is anything but 297af245d11STodd Fiala /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread. 29897ccc294SChaoren Lin Error 299af245d11STodd Fiala SingleStep(lldb::tid_t tid, uint32_t signo); 300af245d11STodd Fiala 301511e5cdcSTodd Fiala void 302fa03ad2eSChaoren Lin NotifyThreadDeath (lldb::tid_t tid); 303fa03ad2eSChaoren Lin 304db264a6dSTamas Berghammer Error 305af245d11STodd Fiala Detach(lldb::tid_t tid); 30686fd8e45SChaoren Lin 307c076559aSPavel Labath 3081dbc6c9cSPavel Labath // This method is requests a stop on all threads which are still running. It sets up a 3091dbc6c9cSPavel Labath // deferred delegate notification, which will fire once threads report as stopped. The 3101dbc6c9cSPavel Labath // triggerring_tid will be set as the current thread (main stop reason). 311c076559aSPavel Labath void 312337f3eb9SPavel Labath StopRunningThreads(lldb::tid_t triggering_tid); 313c076559aSPavel Labath 3149eb1ecb9SPavel Labath // Notify the delegate if all threads have stopped. 3159eb1ecb9SPavel Labath void SignalIfAllThreadsStopped(); 316c076559aSPavel Labath 3170e1d729bSPavel Labath // Resume the given thread, optionally passing it the given signal. The type of resume 3180e1d729bSPavel Labath // operation (continue, single-step) depends on the state parameter. 3195eb721edSPavel Labath Error 3200e1d729bSPavel Labath ResumeThread(const NativeThreadLinuxSP &thread_sp, lldb::StateType state, int signo); 321c076559aSPavel Labath 322c076559aSPavel Labath void 323*f9077782SPavel Labath ThreadWasCreated(NativeThreadLinux &thread); 324c076559aSPavel Labath 32519cbe96aSPavel Labath void 32619cbe96aSPavel Labath SigchldHandler(); 327af245d11STodd Fiala }; 328db264a6dSTamas Berghammer 329db264a6dSTamas Berghammer } // namespace process_linux 330db264a6dSTamas Berghammer } // namespace lldb_private 331af245d11STodd Fiala 332af245d11STodd Fiala #endif // #ifndef liblldb_NativeProcessLinux_H_ 333