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 18c076559aSPavel Labath #include <mutex> 19c076559aSPavel Labath #include <unordered_map> 20af245d11STodd Fiala #include <unordered_set> 21af245d11STodd Fiala 22af245d11STodd Fiala // Other libraries and framework includes 23af245d11STodd Fiala #include "lldb/Core/ArchSpec.h" 24af245d11STodd Fiala #include "lldb/lldb-types.h" 25af245d11STodd Fiala #include "lldb/Host/Debug.h" 2639de3110SZachary Turner #include "lldb/Host/HostThread.h" 27af245d11STodd Fiala #include "lldb/Host/Mutex.h" 28af245d11STodd Fiala #include "lldb/Target/MemoryRegionInfo.h" 29af245d11STodd Fiala 302fe1d0abSChaoren Lin #include "lldb/Host/common/NativeProcessProtocol.h" 31af245d11STodd Fiala 32db264a6dSTamas Berghammer namespace lldb_private { 33af245d11STodd Fiala class Error; 34af245d11STodd Fiala class Module; 35af245d11STodd Fiala class Scalar; 36af245d11STodd Fiala 37db264a6dSTamas Berghammer namespace process_linux { 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 873eb4b458SChaoren Lin ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override; 88af245d11STodd Fiala 89af245d11STodd Fiala Error 903eb4b458SChaoren Lin ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override; 91af245d11STodd Fiala 92af245d11STodd Fiala Error 933eb4b458SChaoren Lin WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) override; 943eb4b458SChaoren Lin 953eb4b458SChaoren Lin Error 963eb4b458SChaoren 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 11345f5cb31SPavel Labath Error 11445f5cb31SPavel Labath SetWatchpoint (lldb::addr_t addr, size_t size, uint32_t watch_flags, bool hardware) override; 11545f5cb31SPavel Labath 11645f5cb31SPavel Labath Error 11745f5cb31SPavel Labath RemoveWatchpoint (lldb::addr_t addr) override; 11845f5cb31SPavel Labath 119af245d11STodd Fiala void 120af245d11STodd Fiala DoStopIDBumped (uint32_t newBumpId) override; 121af245d11STodd Fiala 1228bc34f4dSOleksiy Vyalov void 1238bc34f4dSOleksiy Vyalov Terminate () override; 1248bc34f4dSOleksiy Vyalov 125af245d11STodd Fiala // --------------------------------------------------------------------- 126af245d11STodd Fiala // Interface used by NativeRegisterContext-derived classes. 127af245d11STodd Fiala // --------------------------------------------------------------------- 128af245d11STodd Fiala 129af245d11STodd Fiala /// Reads the contents from the register identified by the given (architecture 130af245d11STodd Fiala /// dependent) offset. 131af245d11STodd Fiala /// 132af245d11STodd Fiala /// This method is provided for use by RegisterContextLinux derivatives. 13397ccc294SChaoren Lin Error 134af245d11STodd Fiala ReadRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name, 135db264a6dSTamas Berghammer unsigned size, RegisterValue &value); 136af245d11STodd Fiala 137af245d11STodd Fiala /// Writes the given value to the register identified by the given 138af245d11STodd Fiala /// (architecture dependent) offset. 139af245d11STodd Fiala /// 140af245d11STodd Fiala /// This method is provided for use by RegisterContextLinux derivatives. 14197ccc294SChaoren Lin Error 142af245d11STodd Fiala WriteRegisterValue(lldb::tid_t tid, unsigned offset, const char *reg_name, 143db264a6dSTamas Berghammer const RegisterValue &value); 144af245d11STodd Fiala 145af245d11STodd Fiala /// Reads all general purpose registers into the specified buffer. 14697ccc294SChaoren Lin Error 147af245d11STodd Fiala ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size); 148af245d11STodd Fiala 149af245d11STodd Fiala /// Reads generic floating point registers into the specified buffer. 15097ccc294SChaoren Lin Error 151af245d11STodd Fiala ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size); 152af245d11STodd Fiala 153af245d11STodd Fiala /// Reads the specified register set into the specified buffer. 154af245d11STodd Fiala /// For instance, the extended floating-point register set. 15597ccc294SChaoren Lin Error 156af245d11STodd Fiala ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset); 157af245d11STodd Fiala 158af245d11STodd Fiala /// Writes all general purpose registers into the specified buffer. 15997ccc294SChaoren Lin Error 160af245d11STodd Fiala WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size); 161af245d11STodd Fiala 162af245d11STodd Fiala /// Writes generic floating point registers into the specified buffer. 16397ccc294SChaoren Lin Error 164af245d11STodd Fiala WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size); 165af245d11STodd Fiala 166af245d11STodd Fiala /// Writes the specified register set into the specified buffer. 167af245d11STodd Fiala /// For instance, the extended floating-point register set. 16897ccc294SChaoren Lin Error 169af245d11STodd Fiala WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset); 170af245d11STodd Fiala 1717cb18bf5STamas Berghammer Error 1727cb18bf5STamas Berghammer GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec) override; 1737cb18bf5STamas Berghammer 174af245d11STodd Fiala protected: 175af245d11STodd Fiala // --------------------------------------------------------------------- 176af245d11STodd Fiala // NativeProcessProtocol protected interface 177af245d11STodd Fiala // --------------------------------------------------------------------- 178af245d11STodd Fiala Error 179af245d11STodd Fiala GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hint, size_t &actual_opcode_size, const uint8_t *&trap_opcode_bytes) override; 180af245d11STodd Fiala 181af245d11STodd Fiala private: 182af245d11STodd Fiala 1831107b5a5SPavel Labath class Monitor; 1841107b5a5SPavel Labath 185db264a6dSTamas Berghammer ArchSpec m_arch; 186af245d11STodd Fiala 1871107b5a5SPavel Labath std::unique_ptr<Monitor> m_monitor_up; 188af245d11STodd Fiala 189db264a6dSTamas Berghammer LazyBool m_supports_mem_region; 190af245d11STodd Fiala std::vector<MemoryRegionInfo> m_mem_region_cache; 191db264a6dSTamas Berghammer Mutex m_mem_region_cache_mutex; 192af245d11STodd Fiala 193d8c338d4STamas Berghammer // List of thread ids stepping with a breakpoint with the address of 194d8c338d4STamas Berghammer // the relevan breakpoint 195d8c338d4STamas Berghammer std::map<lldb::tid_t, lldb::addr_t> m_threads_stepping_with_breakpoint; 196d8c338d4STamas Berghammer 197af245d11STodd Fiala /// @class LauchArgs 198af245d11STodd Fiala /// 199af245d11STodd Fiala /// @brief Simple structure to pass data to the thread responsible for 200af245d11STodd Fiala /// launching a child process. 201bd7cbc5aSPavel Labath struct LaunchArgs 202af245d11STodd Fiala { 203bd7cbc5aSPavel Labath LaunchArgs(Module *module, 204af245d11STodd Fiala char const **argv, 205af245d11STodd Fiala char const **envp, 20675f47c3aSTodd Fiala const std::string &stdin_path, 20775f47c3aSTodd Fiala const std::string &stdout_path, 20875f47c3aSTodd Fiala const std::string &stderr_path, 2090bce1b67STodd Fiala const char *working_dir, 210db264a6dSTamas Berghammer const ProcessLaunchInfo &launch_info); 211af245d11STodd Fiala 212af245d11STodd Fiala ~LaunchArgs(); 213af245d11STodd Fiala 214db264a6dSTamas Berghammer Module *m_module; // The executable image to launch. 215af245d11STodd Fiala char const **m_argv; // Process arguments. 216af245d11STodd Fiala char const **m_envp; // Process environment. 21775f47c3aSTodd Fiala const std::string &m_stdin_path; // Redirect stdin if not empty. 21875f47c3aSTodd Fiala const std::string &m_stdout_path; // Redirect stdout if not empty. 21975f47c3aSTodd Fiala const std::string &m_stderr_path; // Redirect stderr if not empty. 220af245d11STodd Fiala const char *m_working_dir; // Working directory or NULL. 221db264a6dSTamas Berghammer const ProcessLaunchInfo &m_launch_info; 222af245d11STodd Fiala }; 223af245d11STodd Fiala 224bd7cbc5aSPavel Labath typedef std::function<::pid_t(Error &)> InitialOperation; 225af245d11STodd Fiala 226af245d11STodd Fiala // --------------------------------------------------------------------- 227af245d11STodd Fiala // Private Instance Methods 228af245d11STodd Fiala // --------------------------------------------------------------------- 229af245d11STodd Fiala NativeProcessLinux (); 230af245d11STodd Fiala 231af245d11STodd Fiala /// Launches an inferior process ready for debugging. Forms the 232af245d11STodd Fiala /// implementation of Process::DoLaunch. 233af245d11STodd Fiala void 234af245d11STodd Fiala LaunchInferior ( 235af245d11STodd Fiala Module *module, 236af245d11STodd Fiala char const *argv[], 237af245d11STodd Fiala char const *envp[], 23875f47c3aSTodd Fiala const std::string &stdin_path, 23975f47c3aSTodd Fiala const std::string &stdout_path, 24075f47c3aSTodd Fiala const std::string &stderr_path, 241af245d11STodd Fiala const char *working_dir, 242db264a6dSTamas Berghammer const ProcessLaunchInfo &launch_info, 243af245d11STodd Fiala Error &error); 244af245d11STodd Fiala 245af245d11STodd Fiala /// Attaches to an existing process. Forms the 2460cbf0b13STamas Berghammer /// implementation of Process::DoAttach 247af245d11STodd Fiala void 248af245d11STodd Fiala AttachToInferior (lldb::pid_t pid, Error &error); 249af245d11STodd Fiala 250af245d11STodd Fiala void 251bd7cbc5aSPavel Labath StartMonitorThread(const InitialOperation &operation, Error &error); 2521107b5a5SPavel Labath 253bd7cbc5aSPavel Labath ::pid_t 254bd7cbc5aSPavel Labath Launch(LaunchArgs *args, Error &error); 255af245d11STodd Fiala 256bd7cbc5aSPavel Labath ::pid_t 257bd7cbc5aSPavel Labath Attach(lldb::pid_t pid, Error &error); 258af245d11STodd Fiala 25997ccc294SChaoren Lin static Error 260af245d11STodd Fiala SetDefaultPtraceOpts(const lldb::pid_t); 261af245d11STodd Fiala 262af245d11STodd Fiala static bool 263af245d11STodd Fiala DupDescriptor(const char *path, int fd, int flags); 264af245d11STodd Fiala 2651107b5a5SPavel Labath static void * 2661107b5a5SPavel Labath MonitorThread(void *baton); 2671107b5a5SPavel Labath 2681107b5a5SPavel Labath void 2691107b5a5SPavel Labath MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status); 270af245d11STodd Fiala 271af245d11STodd Fiala void 272426bdf88SPavel Labath WaitForNewThread(::pid_t tid); 273426bdf88SPavel Labath 274426bdf88SPavel Labath void 275af245d11STodd Fiala MonitorSIGTRAP(const siginfo_t *info, lldb::pid_t pid); 276af245d11STodd Fiala 277af245d11STodd Fiala void 278c16f5dcaSChaoren Lin MonitorTrace(lldb::pid_t pid, NativeThreadProtocolSP thread_sp); 279c16f5dcaSChaoren Lin 280c16f5dcaSChaoren Lin void 281c16f5dcaSChaoren Lin MonitorBreakpoint(lldb::pid_t pid, NativeThreadProtocolSP thread_sp); 282c16f5dcaSChaoren Lin 283c16f5dcaSChaoren Lin void 284c16f5dcaSChaoren Lin MonitorWatchpoint(lldb::pid_t pid, NativeThreadProtocolSP thread_sp, uint32_t wp_index); 285c16f5dcaSChaoren Lin 286c16f5dcaSChaoren Lin void 287af245d11STodd Fiala MonitorSignal(const siginfo_t *info, lldb::pid_t pid, bool exited); 288af245d11STodd Fiala 289e7708688STamas Berghammer bool 290e7708688STamas Berghammer SupportHardwareSingleStepping() const; 291e7708688STamas Berghammer 292e7708688STamas Berghammer Error 293e7708688STamas Berghammer SetupSoftwareSingleStepping(NativeThreadProtocolSP thread_sp); 294e7708688STamas Berghammer 295af245d11STodd Fiala #if 0 296af245d11STodd Fiala static ::ProcessMessage::CrashReason 297af245d11STodd Fiala GetCrashReasonForSIGSEGV(const siginfo_t *info); 298af245d11STodd Fiala 299af245d11STodd Fiala static ::ProcessMessage::CrashReason 300af245d11STodd Fiala GetCrashReasonForSIGILL(const siginfo_t *info); 301af245d11STodd Fiala 302af245d11STodd Fiala static ::ProcessMessage::CrashReason 303af245d11STodd Fiala GetCrashReasonForSIGFPE(const siginfo_t *info); 304af245d11STodd Fiala 305af245d11STodd Fiala static ::ProcessMessage::CrashReason 306af245d11STodd Fiala GetCrashReasonForSIGBUS(const siginfo_t *info); 307af245d11STodd Fiala #endif 308af245d11STodd Fiala 309af245d11STodd Fiala bool 310af245d11STodd Fiala HasThreadNoLock (lldb::tid_t thread_id); 311af245d11STodd Fiala 312af245d11STodd Fiala NativeThreadProtocolSP 313af245d11STodd Fiala MaybeGetThreadNoLock (lldb::tid_t thread_id); 314af245d11STodd Fiala 315af245d11STodd Fiala bool 316af245d11STodd Fiala StopTrackingThread (lldb::tid_t thread_id); 317af245d11STodd Fiala 318af245d11STodd Fiala NativeThreadProtocolSP 319af245d11STodd Fiala AddThread (lldb::tid_t thread_id); 320af245d11STodd Fiala 321af245d11STodd Fiala Error 32263c8be95STamas Berghammer GetSoftwareBreakpointPCOffset (NativeRegisterContextSP context_sp, uint32_t &actual_opcode_size); 323af245d11STodd Fiala 324af245d11STodd Fiala Error 325af245d11STodd Fiala FixupBreakpointPCAsNeeded (NativeThreadProtocolSP &thread_sp); 326af245d11STodd Fiala 327af245d11STodd Fiala /// Writes a siginfo_t structure corresponding to the given thread ID to the 328af245d11STodd Fiala /// memory region pointed to by @p siginfo. 32997ccc294SChaoren Lin Error 33097ccc294SChaoren Lin GetSignalInfo(lldb::tid_t tid, void *siginfo); 331af245d11STodd Fiala 332af245d11STodd Fiala /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG) 333af245d11STodd Fiala /// corresponding to the given thread ID to the memory pointed to by @p 334af245d11STodd Fiala /// message. 33597ccc294SChaoren Lin Error 336af245d11STodd Fiala GetEventMessage(lldb::tid_t tid, unsigned long *message); 337af245d11STodd Fiala 338af245d11STodd Fiala /// Resumes the given thread. If @p signo is anything but 339af245d11STodd Fiala /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread. 34097ccc294SChaoren Lin Error 341af245d11STodd Fiala Resume(lldb::tid_t tid, uint32_t signo); 342af245d11STodd Fiala 343af245d11STodd Fiala /// Single steps the given thread. If @p signo is anything but 344af245d11STodd Fiala /// LLDB_INVALID_SIGNAL_NUMBER, deliver that signal to the thread. 34597ccc294SChaoren Lin Error 346af245d11STodd Fiala SingleStep(lldb::tid_t tid, uint32_t signo); 347af245d11STodd Fiala 348fa03ad2eSChaoren Lin // ThreadStateCoordinator helper methods. 349511e5cdcSTodd Fiala void 350fa03ad2eSChaoren Lin NotifyThreadCreateStopped (lldb::tid_t tid); 351511e5cdcSTodd Fiala 352511e5cdcSTodd Fiala void 353fa03ad2eSChaoren Lin NotifyThreadCreateRunning (lldb::tid_t tid); 354fa03ad2eSChaoren Lin 355fa03ad2eSChaoren Lin void 356fa03ad2eSChaoren Lin NotifyThreadDeath (lldb::tid_t tid); 357fa03ad2eSChaoren Lin 358fa03ad2eSChaoren Lin void 359fa03ad2eSChaoren Lin NotifyThreadStop (lldb::tid_t tid); 360fa03ad2eSChaoren Lin 361fa03ad2eSChaoren Lin void 362*ed89c7feSPavel Labath StopRunningThreads (lldb::tid_t triggering_tid); 363511e5cdcSTodd Fiala 36403f12d6bSChaoren Lin void 365*ed89c7feSPavel Labath StopRunningThreadsWithSkipTID (lldb::tid_t deferred_signal_tid, 366*ed89c7feSPavel Labath lldb::tid_t skip_stop_request_tid); 36703f12d6bSChaoren Lin 368db264a6dSTamas Berghammer Error 369af245d11STodd Fiala Detach(lldb::tid_t tid); 37086fd8e45SChaoren Lin 371db264a6dSTamas Berghammer Error 37286fd8e45SChaoren Lin RequestThreadStop (const lldb::pid_t pid, const lldb::tid_t tid); 373c076559aSPavel Labath 374c076559aSPavel Labath 375c076559aSPavel Labath public: 376c076559aSPavel Labath // Typedefs. 377c076559aSPavel Labath typedef std::unordered_set<lldb::tid_t> ThreadIDSet; 378c076559aSPavel Labath 379c076559aSPavel Labath // Callback/block definitions. 380c076559aSPavel Labath typedef std::function<void (const char *format, va_list args)> LogFunction; 381c076559aSPavel Labath typedef std::function<void (const std::string &error_message)> ErrorFunction; 382c076559aSPavel Labath typedef std::function<Error (lldb::tid_t tid)> StopThreadFunction; 383c076559aSPavel Labath typedef std::function<Error (lldb::tid_t tid, bool supress_signal)> ResumeThreadFunction; 384c076559aSPavel Labath 385c076559aSPavel Labath private: 386c076559aSPavel Labath // Notify the coordinator when a thread is created and/or starting to be 387c076559aSPavel Labath // tracked. is_stopped should be true if the thread is currently stopped; 388c076559aSPavel Labath // otherwise, it should be set false if it is already running. Will 389c076559aSPavel Labath // call the error function if the thread id is already tracked. 390c076559aSPavel Labath void 391c076559aSPavel Labath NotifyThreadCreate (lldb::tid_t tid, 392c076559aSPavel Labath bool is_stopped, 393c076559aSPavel Labath const ErrorFunction &error_function); 394c076559aSPavel Labath 395c076559aSPavel Labath // Notify the coordinator when a previously-existing thread should no 396c076559aSPavel Labath // longer be tracked. The error_function will trigger if the thread 397c076559aSPavel Labath // is not being tracked. 398c076559aSPavel Labath void 399c076559aSPavel Labath NotifyThreadDeath (lldb::tid_t tid, 400c076559aSPavel Labath const ErrorFunction &error_function); 401c076559aSPavel Labath 402c076559aSPavel Labath 403*ed89c7feSPavel Labath // Notify the delegate after a given set of threads stops. The triggering_tid will be set 404*ed89c7feSPavel Labath // as the current thread. The error_function will be fired if either the triggering tid 405*ed89c7feSPavel Labath // or any of the wait_for_stop_tids are unknown. 406c076559aSPavel Labath void 407*ed89c7feSPavel Labath StopThreads(lldb::tid_t triggering_tid, 408c076559aSPavel Labath const ThreadIDSet &wait_for_stop_tids, 409c076559aSPavel Labath const StopThreadFunction &request_thread_stop_function, 410c076559aSPavel Labath const ErrorFunction &error_function); 411c076559aSPavel Labath 412*ed89c7feSPavel Labath // Notify the delegate after all non-stopped threads stop. The triggering_tid will be set 413*ed89c7feSPavel Labath // as the current thread. The error_function will be fired if the triggering tid 414*ed89c7feSPavel Labath // is unknown. 415c076559aSPavel Labath void 416*ed89c7feSPavel Labath StopRunningThreads(lldb::tid_t triggering_tid, 417c076559aSPavel Labath const StopThreadFunction &request_thread_stop_function, 418c076559aSPavel Labath const ErrorFunction &error_function); 419c076559aSPavel Labath 420*ed89c7feSPavel Labath // Notify the delegate after all non-stopped threads stop. The triggering_tid will be set 421*ed89c7feSPavel Labath // as the current thread. The error_function will be fired if either the triggering tid 422*ed89c7feSPavel Labath // or any of the wait_for_stop_tids are unknown. This variant will send stop requests to 423*ed89c7feSPavel Labath // all non-stopped threads except for any contained in skip_stop_request_tids. 424c076559aSPavel Labath void 425*ed89c7feSPavel Labath StopRunningThreadsWithSkipTID(lldb::tid_t triggering_tid, 426c076559aSPavel Labath const ThreadIDSet &skip_stop_request_tids, 427c076559aSPavel Labath const StopThreadFunction &request_thread_stop_function, 428c076559aSPavel Labath const ErrorFunction &error_function); 429c076559aSPavel Labath 430c076559aSPavel Labath // Notify the thread stopped. Will trigger error at time of execution if we 431c076559aSPavel Labath // already think it is stopped. 432c076559aSPavel Labath void 433c076559aSPavel Labath NotifyThreadStop (lldb::tid_t tid, 434c076559aSPavel Labath bool initiated_by_llgs, 435c076559aSPavel Labath const ErrorFunction &error_function); 436c076559aSPavel Labath 437c076559aSPavel Labath // Request that the given thread id should have the request_thread_resume_function 438c076559aSPavel Labath // called. Will trigger the error_function if the thread is thought to be running 439c076559aSPavel Labath // already at that point. This call signals an error if the thread resume is for 440c076559aSPavel Labath // a thread that is already in a running state. 441c076559aSPavel Labath void 442c076559aSPavel Labath RequestThreadResume (lldb::tid_t tid, 443c076559aSPavel Labath const ResumeThreadFunction &request_thread_resume_function, 444c076559aSPavel Labath const ErrorFunction &error_function); 445c076559aSPavel Labath 446c076559aSPavel Labath // Request that the given thread id should have the request_thread_resume_function 447c076559aSPavel Labath // called. Will trigger the error_function if the thread is thought to be running 448c076559aSPavel Labath // already at that point. This call ignores threads that are already running and 449c076559aSPavel Labath // does not trigger an error in that case. 450c076559aSPavel Labath void 451c076559aSPavel Labath RequestThreadResumeAsNeeded (lldb::tid_t tid, 452c076559aSPavel Labath const ResumeThreadFunction &request_thread_resume_function, 453c076559aSPavel Labath const ErrorFunction &error_function); 454c076559aSPavel Labath 455c076559aSPavel Labath // Indicate the calling process did an exec and that the thread state 456c076559aSPavel Labath // should be 100% cleared. 457c076559aSPavel Labath void 458c076559aSPavel Labath ResetForExec (); 459c076559aSPavel Labath 460c076559aSPavel Labath // Enable/disable verbose logging of event processing. 461c076559aSPavel Labath void 462c076559aSPavel Labath LogEnableEventProcessing (bool enabled); 463c076559aSPavel Labath 464c076559aSPavel Labath private: 465c076559aSPavel Labath 466c076559aSPavel Labath enum class ThreadState 467c076559aSPavel Labath { 468c076559aSPavel Labath Running, 469c076559aSPavel Labath Stopped 470c076559aSPavel Labath }; 471c076559aSPavel Labath 472c076559aSPavel Labath struct ThreadContext 473c076559aSPavel Labath { 474c076559aSPavel Labath ThreadState m_state; 475c076559aSPavel Labath bool m_stop_requested = false; 476c076559aSPavel Labath ResumeThreadFunction m_request_resume_function; 477c076559aSPavel Labath }; 478c076559aSPavel Labath typedef std::unordered_map<lldb::tid_t, ThreadContext> TIDContextMap; 479c076559aSPavel Labath 480c076559aSPavel Labath struct PendingNotification 481c076559aSPavel Labath { 482c076559aSPavel Labath PendingNotification (lldb::tid_t triggering_tid, 483c076559aSPavel Labath const ThreadIDSet &wait_for_stop_tids, 484c076559aSPavel Labath const StopThreadFunction &request_thread_stop_function, 485c076559aSPavel Labath const ErrorFunction &error_function): 486c076559aSPavel Labath triggering_tid (triggering_tid), 487c076559aSPavel Labath wait_for_stop_tids (wait_for_stop_tids), 488c076559aSPavel Labath original_wait_for_stop_tids (wait_for_stop_tids), 489c076559aSPavel Labath request_thread_stop_function (request_thread_stop_function), 490c076559aSPavel Labath error_function (error_function), 491c076559aSPavel Labath request_stop_on_all_unstopped_threads (false), 492c076559aSPavel Labath skip_stop_request_tids () 493c076559aSPavel Labath { 494c076559aSPavel Labath } 495c076559aSPavel Labath 496c076559aSPavel Labath PendingNotification (lldb::tid_t triggering_tid, 497c076559aSPavel Labath const StopThreadFunction &request_thread_stop_function, 498c076559aSPavel Labath const ErrorFunction &error_function) : 499c076559aSPavel Labath triggering_tid (triggering_tid), 500c076559aSPavel Labath wait_for_stop_tids (), 501c076559aSPavel Labath original_wait_for_stop_tids (), 502c076559aSPavel Labath request_thread_stop_function (request_thread_stop_function), 503c076559aSPavel Labath error_function (error_function), 504c076559aSPavel Labath request_stop_on_all_unstopped_threads (true), 505c076559aSPavel Labath skip_stop_request_tids () 506c076559aSPavel Labath { 507c076559aSPavel Labath } 508c076559aSPavel Labath 509c076559aSPavel Labath PendingNotification (lldb::tid_t triggering_tid, 510c076559aSPavel Labath const StopThreadFunction &request_thread_stop_function, 511c076559aSPavel Labath const ThreadIDSet &skip_stop_request_tids, 512c076559aSPavel Labath const ErrorFunction &error_function) : 513c076559aSPavel Labath triggering_tid (triggering_tid), 514c076559aSPavel Labath wait_for_stop_tids (), 515c076559aSPavel Labath original_wait_for_stop_tids (), 516c076559aSPavel Labath request_thread_stop_function (request_thread_stop_function), 517c076559aSPavel Labath error_function (error_function), 518c076559aSPavel Labath request_stop_on_all_unstopped_threads (true), 519c076559aSPavel Labath skip_stop_request_tids (skip_stop_request_tids) 520c076559aSPavel Labath { 521c076559aSPavel Labath } 522c076559aSPavel Labath 523c076559aSPavel Labath const lldb::tid_t triggering_tid; 524c076559aSPavel Labath ThreadIDSet wait_for_stop_tids; 525c076559aSPavel Labath const ThreadIDSet original_wait_for_stop_tids; 526c076559aSPavel Labath StopThreadFunction request_thread_stop_function; 527c076559aSPavel Labath ErrorFunction error_function; 528c076559aSPavel Labath const bool request_stop_on_all_unstopped_threads; 529c076559aSPavel Labath ThreadIDSet skip_stop_request_tids; 530c076559aSPavel Labath }; 531c076559aSPavel Labath typedef std::unique_ptr<PendingNotification> PendingNotificationUP; 532c076559aSPavel Labath 533c076559aSPavel Labath // Fire pending notification if no pending thread stops remain. 534c076559aSPavel Labath void SignalIfRequirementsSatisfied(); 535c076559aSPavel Labath 536c076559aSPavel Labath bool 537c076559aSPavel Labath RequestStopOnAllSpecifiedThreads(); 538c076559aSPavel Labath 539c076559aSPavel Labath void 540c076559aSPavel Labath RequestStopOnAllRunningThreads(); 541c076559aSPavel Labath 542c076559aSPavel Labath void 543c076559aSPavel Labath RequestThreadStop (lldb::tid_t tid, ThreadContext& context); 544c076559aSPavel Labath 545c076559aSPavel Labath std::mutex m_event_mutex; // Serializes execution of ProcessEvent. XXX 546c076559aSPavel Labath 547c076559aSPavel Labath void 548c076559aSPavel Labath ThreadDidStop (lldb::tid_t tid, bool initiated_by_llgs, const ErrorFunction &error_function); 549c076559aSPavel Labath 550c076559aSPavel Labath void 551c076559aSPavel Labath DoResume(lldb::tid_t tid, ResumeThreadFunction request_thread_resume_function, 552c076559aSPavel Labath ErrorFunction error_function, bool error_when_already_running); 553c076559aSPavel Labath 554c076559aSPavel Labath void 555*ed89c7feSPavel Labath DoStopThreads(PendingNotificationUP &¬ification_up); 556c076559aSPavel Labath 557c076559aSPavel Labath void 558c076559aSPavel Labath ThreadWasCreated (lldb::tid_t tid, bool is_stopped, const ErrorFunction &error_function); 559c076559aSPavel Labath 560c076559aSPavel Labath void 561c076559aSPavel Labath ThreadDidDie (lldb::tid_t tid, const ErrorFunction &error_function); 562c076559aSPavel Labath 563c076559aSPavel Labath bool 564c076559aSPavel Labath IsKnownThread(lldb::tid_t tid) const; 565c076559aSPavel Labath 566c076559aSPavel Labath void 567c076559aSPavel Labath TSCLog (const char *format, ...); 568c076559aSPavel Labath 569c076559aSPavel Labath // Member variables. 570c076559aSPavel Labath LogFunction m_log_function; 571c076559aSPavel Labath PendingNotificationUP m_pending_notification_up; 572c076559aSPavel Labath 573c076559aSPavel Labath // Maps known TIDs to ThreadContext. 574c076559aSPavel Labath TIDContextMap m_tid_map; 575c076559aSPavel Labath 576c076559aSPavel Labath bool m_log_event_processing; 577af245d11STodd Fiala }; 578db264a6dSTamas Berghammer 579db264a6dSTamas Berghammer } // namespace process_linux 580db264a6dSTamas Berghammer } // namespace lldb_private 581af245d11STodd Fiala 582af245d11STodd Fiala #endif // #ifndef liblldb_NativeProcessLinux_H_ 583