13#include "DebugServer2/GDBRemote/Mixins/ProcessLaunchMixin.h"
22ErrorCode ProcessLaunchMixin<T>::onDisableASLR(Session &session,
bool disable) {
23 _disableASLR = disable;
29ProcessLaunchMixin<T>::onSetArchitecture(Session &,
30 std::string
const &architecture) {
37ProcessLaunchMixin<T>::onSetWorkingDirectory(Session &,
38 std::string
const &path) {
51 std::filesystem::path resolved(path);
52 if (!resolved.is_absolute())
53 resolved = std::filesystem::path(Platform::GetWorkingDirectory()) / resolved;
55 _workingDirectory = resolved.string();
61ProcessLaunchMixin<T>::onQueryWorkingDirectory(Session &,
62 std::string &workingDir)
const {
63 workingDir = _workingDirectory;
68ErrorCode ProcessLaunchMixin<T>::onSetEnvironmentVariable(Session &,
69 std::string
const &name, std::string
const &value) {
71 _environment.erase(name);
73 _environment.insert(std::make_pair(name, value));
79ErrorCode ProcessLaunchMixin<T>::onSetStdFile(Session &,
int fileno,
80 std::string
const &path) {
81 DS2LOG(Debug,
"stdfile[%d] = %s", fileno, path.c_str());
83 if (fileno < 0 || fileno > 2)
84 return kErrorInvalidArgument;
95 _workingDirectory.clear();
101 _stdFile[fileno] = path;
107ProcessLaunchMixin<T>::onSetProgramArguments(Session &,
108 StringCollection
const &args) {
110 if (isDebugServer(args)) {
113 if (GetLogLevel() == kLogLevelDebug)
114 _arguments.push_back(
"--debug");
115 else if (GetLogLevel() == kLogLevelPacket)
116 _arguments.push_back(
"--remote-debug");
119 return spawnProcess();
124ErrorCode ProcessLaunchMixin<T>::onQueryLaunchSuccess(Session &,
126 return _lastLaunchResult;
131ProcessLaunchMixin<T>::onQueryProcessInfo(Session &,
132 ProcessInfo &info)
const {
133 if (_processList.empty())
134 return kErrorProcessNotFound;
136 const ProcessId pid = _processList.back();
137 if (!Platform::GetProcessInfo(pid, info))
138 return kErrorUnknown;
144ErrorCode ProcessLaunchMixin<T>::onTerminate(Session &session,
145 ProcessThreadId
const &ptid,
147 auto it = std::find(_processList.begin(), _processList.end(), ptid.pid);
148 if (it == _processList.end())
149 return kErrorNotFound;
151 if (!Platform::TerminateProcess(ptid.pid))
152 return kErrorUnknown;
154 DS2LOG(Debug,
"killed spawned process %" PRI_PID, *it);
155 _processList.erase(it);
169bool ProcessLaunchMixin<T>::isDebugServer(StringCollection
const &args) {
170 return (args.size() > 1)
171 && (args[0] == Platform::GetSelfExecutablePath())
172 && (args[1] ==
"gdbserver");
176ErrorCode ProcessLaunchMixin<T>::spawnProcess() {
177 const bool displayArgs = _arguments.size() > 1;
178 const bool displayEnv = !_environment.empty();
179 auto it = _arguments.begin();
180 DS2LOG(Debug,
"spawning process '%s'%s", (it++)->c_str(),
181 displayArgs ?
" with args:" :
"");
182 while (it != _arguments.end()) {
183 DS2LOG(Debug,
" %s", (it++)->c_str());
187 DS2LOG(Debug,
"%swith environment:", displayArgs ?
"and " :
"");
188 for (
auto const &val : _environment) {
189 DS2LOG(Debug,
" %s=%s", val.first.c_str(), val.second.c_str());
193 if (!_workingDirectory.empty()) {
194 DS2LOG(Debug,
"%swith working directory: %s",
195 displayArgs || displayEnv ?
"and " :
"",
196 _workingDirectory.c_str());
199 Host::ProcessSpawner ps;
200 if (!ps.setExecutable(_arguments[0]) ||
201 !ps.setArguments(StringCollection(_arguments.begin() + 1,
202 _arguments.end())) ||
203 !ps.setWorkingDirectory(_workingDirectory) ||
204 !ps.setEnvironment(_environment))
205 return kErrorInvalidArgument;
207 if (isDebugServer(_arguments)) {
210 ps.redirectInputToNull();
211 ps.redirectOutputToConsole();
212 ps.redirectErrorToConsole();
214 if (!_stdFile[0].empty() && !ps.redirectInputToFile(_stdFile[0]))
215 return kErrorInvalidArgument;
216 if (!_stdFile[1].empty() && !ps.redirectOutputToFile(_stdFile[1]))
217 return kErrorInvalidArgument;
218 if (!_stdFile[2].empty() && !ps.redirectErrorToFile(_stdFile[2]))
219 return kErrorInvalidArgument;
222 _lastLaunchResult = ps.run();
223 if (_lastLaunchResult != kSuccess)
224 return _lastLaunchResult;
228 _processList.push_back(ps.pid());
230 DS2LOG(Debug,
"launched %s as process %" PRI_PID, _arguments[0].c_str(),