xref: /openbsd-src/gnu/llvm/lldb/tools/debugserver/source/RNBContext.h (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
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