1061da546Spatrick //===-- RNBContext.h --------------------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick // 9061da546Spatrick // Created by Greg Clayton on 12/12/07. 10061da546Spatrick // 11061da546Spatrick //===----------------------------------------------------------------------===// 12061da546Spatrick 13dda28197Spatrick #ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBCONTEXT_H 14dda28197Spatrick #define LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBCONTEXT_H 15061da546Spatrick 16061da546Spatrick #include "DNBError.h" 17061da546Spatrick #include "PThreadEvent.h" 18061da546Spatrick #include "RNBDefs.h" 19061da546Spatrick #include <string> 20061da546Spatrick #include <vector> 21061da546Spatrick 22061da546Spatrick class RNBContext { 23061da546Spatrick public: 24*f6aab3d8Srobert using IgnoredExceptions = std::vector<exception_mask_t>; 25061da546Spatrick enum { 26061da546Spatrick event_proc_state_changed = 0x001, 27061da546Spatrick event_proc_thread_running = 0x002, // Sticky 28061da546Spatrick event_proc_thread_exiting = 0x004, 29061da546Spatrick event_proc_stdio_available = 0x008, 30061da546Spatrick event_proc_profile_data = 0x010, 31061da546Spatrick event_read_packet_available = 0x020, 32061da546Spatrick event_read_thread_running = 0x040, // Sticky 33061da546Spatrick event_read_thread_exiting = 0x080, 34061da546Spatrick 35061da546Spatrick normal_event_bits = event_proc_state_changed | event_proc_thread_exiting | 36061da546Spatrick event_proc_stdio_available | event_proc_profile_data | 37061da546Spatrick event_read_packet_available | 38be691f3bSpatrick event_read_thread_exiting , 39061da546Spatrick 40061da546Spatrick sticky_event_bits = event_proc_thread_running | event_read_thread_running, 41061da546Spatrick 42061da546Spatrick all_event_bits = sticky_event_bits | normal_event_bits 43061da546Spatrick } event_t; 44061da546Spatrick // Constructors and Destructors 45be691f3bSpatrick RNBContext() = default; 46061da546Spatrick virtual ~RNBContext(); 47061da546Spatrick ProcessID()48061da546Spatrick nub_process_t ProcessID() const { return m_pid; } HasValidProcessID()49061da546Spatrick bool HasValidProcessID() const { return m_pid != INVALID_NUB_PROCESS; } 50061da546Spatrick void SetProcessID(nub_process_t pid); GetProcessStopCount()51061da546Spatrick nub_size_t GetProcessStopCount() const { return m_pid_stop_count; } SetProcessStopCount(nub_size_t count)52061da546Spatrick bool SetProcessStopCount(nub_size_t count) { 53061da546Spatrick // Returns true if this class' notion of the PID state changed 54061da546Spatrick if (m_pid_stop_count == count) 55061da546Spatrick return false; // Didn't change 56061da546Spatrick m_pid_stop_count = count; 57061da546Spatrick return true; // The stop count has changed. 58061da546Spatrick } 59061da546Spatrick 60061da546Spatrick bool ProcessStateRunning() const; Events()61061da546Spatrick PThreadEvent &Events() { return m_events; } AllEventBits()62061da546Spatrick nub_event_t AllEventBits() const { return all_event_bits; } NormalEventBits()63061da546Spatrick nub_event_t NormalEventBits() const { return normal_event_bits; } StickyEventBits()64061da546Spatrick nub_event_t StickyEventBits() const { return sticky_event_bits; } 65061da546Spatrick const char *EventsAsString(nub_event_t events, std::string &s); 66061da546Spatrick ArgumentCount()67061da546Spatrick size_t ArgumentCount() const { return m_arg_vec.size(); } 68061da546Spatrick const char *ArgumentAtIndex(size_t index); PushArgument(const char * arg)69061da546Spatrick void PushArgument(const char *arg) { 70061da546Spatrick if (arg) 71061da546Spatrick m_arg_vec.push_back(arg); 72061da546Spatrick } ClearArgv()73061da546Spatrick void ClearArgv() { m_arg_vec.erase(m_arg_vec.begin(), m_arg_vec.end()); } 74061da546Spatrick EnvironmentCount()75061da546Spatrick size_t EnvironmentCount() const { return m_env_vec.size(); } 76061da546Spatrick const char *EnvironmentAtIndex(size_t index); PushEnvironment(const char * arg)77061da546Spatrick void PushEnvironment(const char *arg) { 78061da546Spatrick if (arg) 79061da546Spatrick m_env_vec.push_back(arg); 80061da546Spatrick } 81061da546Spatrick void PushEnvironmentIfNeeded(const char *arg); ClearEnvironment()82061da546Spatrick void ClearEnvironment() { 83061da546Spatrick m_env_vec.erase(m_env_vec.begin(), m_env_vec.end()); 84061da546Spatrick } LaunchStatus()85061da546Spatrick DNBError &LaunchStatus() { return m_launch_status; } 86061da546Spatrick const char *LaunchStatusAsString(std::string &s); LaunchFlavor()87061da546Spatrick nub_launch_flavor_t LaunchFlavor() const { return m_launch_flavor; } SetLaunchFlavor(nub_launch_flavor_t flavor)88061da546Spatrick void SetLaunchFlavor(nub_launch_flavor_t flavor) { m_launch_flavor = flavor; } 89061da546Spatrick GetWorkingDirectory()90061da546Spatrick const char *GetWorkingDirectory() const { 91061da546Spatrick if (!m_working_directory.empty()) 92061da546Spatrick return m_working_directory.c_str(); 93061da546Spatrick return NULL; 94061da546Spatrick } 95061da546Spatrick 96061da546Spatrick bool SetWorkingDirectory(const char *path); 97061da546Spatrick GetSTDIN()98061da546Spatrick std::string &GetSTDIN() { return m_stdin; } GetSTDOUT()99061da546Spatrick std::string &GetSTDOUT() { return m_stdout; } GetSTDERR()100061da546Spatrick std::string &GetSTDERR() { return m_stderr; } GetWorkingDir()101061da546Spatrick std::string &GetWorkingDir() { return m_working_dir; } 102061da546Spatrick GetSTDINPath()103061da546Spatrick const char *GetSTDINPath() { 104061da546Spatrick return m_stdin.empty() ? NULL : m_stdin.c_str(); 105061da546Spatrick } GetSTDOUTPath()106061da546Spatrick const char *GetSTDOUTPath() { 107061da546Spatrick return m_stdout.empty() ? NULL : m_stdout.c_str(); 108061da546Spatrick } GetSTDERRPath()109061da546Spatrick const char *GetSTDERRPath() { 110061da546Spatrick return m_stderr.empty() ? NULL : m_stderr.c_str(); 111061da546Spatrick } GetWorkingDirPath()112061da546Spatrick const char *GetWorkingDirPath() { 113061da546Spatrick return m_working_dir.empty() ? NULL : m_working_dir.c_str(); 114061da546Spatrick } 115061da546Spatrick PushProcessEvent(const char * p)116061da546Spatrick void PushProcessEvent(const char *p) { m_process_event.assign(p); } GetProcessEvent()117061da546Spatrick const char *GetProcessEvent() { return m_process_event.c_str(); } 118061da546Spatrick SetDetachOnError(bool detach)119061da546Spatrick void SetDetachOnError(bool detach) { m_detach_on_error = detach; } GetDetachOnError()120061da546Spatrick bool GetDetachOnError() { return m_detach_on_error; } 121061da546Spatrick 122*f6aab3d8Srobert bool AddIgnoredException(const char *exception_name); 123*f6aab3d8Srobert 124*f6aab3d8Srobert void AddDefaultIgnoredExceptions(); 125*f6aab3d8Srobert GetIgnoredExceptions()126*f6aab3d8Srobert const IgnoredExceptions &GetIgnoredExceptions() { 127*f6aab3d8Srobert return m_ignored_exceptions; 128be691f3bSpatrick } 129be691f3bSpatrick 130061da546Spatrick protected: 131061da546Spatrick // Classes that inherit from RNBContext can see and modify these 132be691f3bSpatrick nub_process_t m_pid = INVALID_NUB_PROCESS; 133061da546Spatrick std::string m_stdin; 134061da546Spatrick std::string m_stdout; 135061da546Spatrick std::string m_stderr; 136061da546Spatrick std::string m_working_dir; 137be691f3bSpatrick nub_size_t m_pid_stop_count = 0; 138be691f3bSpatrick /// Threaded events that we can wait for. 139be691f3bSpatrick PThreadEvent m_events{0, all_event_bits}; 140061da546Spatrick pthread_t m_pid_pthread; 141be691f3bSpatrick /// How to launch our inferior process. 142be691f3bSpatrick nub_launch_flavor_t m_launch_flavor = eLaunchFlavorDefault; 143be691f3bSpatrick /// This holds the status from the last launch attempt. 144be691f3bSpatrick DNBError m_launch_status; 145061da546Spatrick std::vector<std::string> m_arg_vec; 146be691f3bSpatrick /// This will be unparsed entries FOO=value 147be691f3bSpatrick std::vector<std::string> m_env_vec; 148061da546Spatrick std::string m_working_directory; 149061da546Spatrick std::string m_process_event; 150be691f3bSpatrick bool m_detach_on_error = false; 151*f6aab3d8Srobert IgnoredExceptions m_ignored_exceptions; 152061da546Spatrick 153061da546Spatrick void StartProcessStatusThread(); 154061da546Spatrick void StopProcessStatusThread(); 155061da546Spatrick static void *ThreadFunctionProcessStatus(void *arg); 156061da546Spatrick 157061da546Spatrick private: 158061da546Spatrick RNBContext(const RNBContext &rhs) = delete; 159061da546Spatrick RNBContext &operator=(const RNBContext &rhs) = delete; 160061da546Spatrick }; 161061da546Spatrick 162dda28197Spatrick #endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_RNBCONTEXT_H 163