13#include "DebugServer2/GDBRemote/Mixins/ProcessLaunchMixin.h"
21ErrorCode ProcessLaunchMixin<T>::onDisableASLR(Session &session,
bool disable) {
22 _disableASLR = disable;
28ProcessLaunchMixin<T>::onSetArchitecture(Session &,
29 std::string
const &architecture) {
36ProcessLaunchMixin<T>::onSetWorkingDirectory(Session &,
37 std::string
const &path) {
38 _workingDirectory = path;
44ProcessLaunchMixin<T>::onQueryWorkingDirectory(Session &,
45 std::string &workingDir)
const {
46 workingDir = _workingDirectory;
51ErrorCode ProcessLaunchMixin<T>::onSetEnvironmentVariable(Session &,
52 std::string
const &name, std::string
const &value) {
54 _environment.erase(name);
56 _environment.insert(std::make_pair(name, value));
62ErrorCode ProcessLaunchMixin<T>::onSetStdFile(Session &,
int fileno,
63 std::string
const &path) {
64 DS2LOG(Debug,
"stdfile[%d] = %s", fileno, path.c_str());
66 if (fileno < 0 || fileno > 2)
67 return kErrorInvalidArgument;
78 _workingDirectory.clear();
84 _stdFile[fileno] = path;
90ProcessLaunchMixin<T>::onSetProgramArguments(Session &,
91 StringCollection
const &args) {
93 if (isDebugServer(args)) {
96 if (GetLogLevel() == kLogLevelDebug)
97 _arguments.push_back(
"--debug");
98 else if (GetLogLevel() == kLogLevelPacket)
99 _arguments.push_back(
"--remote-debug");
102 return spawnProcess();
107ErrorCode ProcessLaunchMixin<T>::onQueryLaunchSuccess(Session &,
109 return _lastLaunchResult;
114ProcessLaunchMixin<T>::onQueryProcessInfo(Session &,
115 ProcessInfo &info)
const {
116 if (_processList.empty())
117 return kErrorProcessNotFound;
119 const ProcessId pid = _processList.back();
120 if (!Platform::GetProcessInfo(pid, info))
121 return kErrorUnknown;
127ErrorCode ProcessLaunchMixin<T>::onTerminate(Session &session,
128 ProcessThreadId
const &ptid,
130 auto it = std::find(_processList.begin(), _processList.end(), ptid.pid);
131 if (it == _processList.end())
132 return kErrorNotFound;
134 if (!Platform::TerminateProcess(ptid.pid))
135 return kErrorUnknown;
137 DS2LOG(Debug,
"killed spawned process %" PRI_PID, *it);
138 _processList.erase(it);
152bool ProcessLaunchMixin<T>::isDebugServer(StringCollection
const &args) {
153 return (args.size() > 1)
154 && (args[0] == Platform::GetSelfExecutablePath())
155 && (args[1] ==
"gdbserver");
159ErrorCode ProcessLaunchMixin<T>::spawnProcess() {
160 const bool displayArgs = _arguments.size() > 1;
161 const bool displayEnv = !_environment.empty();
162 auto it = _arguments.begin();
163 DS2LOG(Debug,
"spawning process '%s'%s", (it++)->c_str(),
164 displayArgs ?
" with args:" :
"");
165 while (it != _arguments.end()) {
166 DS2LOG(Debug,
" %s", (it++)->c_str());
170 DS2LOG(Debug,
"%swith environment:", displayArgs ?
"and " :
"");
171 for (
auto const &val : _environment) {
172 DS2LOG(Debug,
" %s=%s", val.first.c_str(), val.second.c_str());
176 if (!_workingDirectory.empty()) {
177 DS2LOG(Debug,
"%swith working directory: %s",
178 displayArgs || displayEnv ?
"and " :
"",
179 _workingDirectory.c_str());
182 Host::ProcessSpawner ps;
183 if (!ps.setExecutable(_arguments[0]) ||
184 !ps.setArguments(StringCollection(_arguments.begin() + 1,
185 _arguments.end())) ||
186 !ps.setWorkingDirectory(_workingDirectory) ||
187 !ps.setEnvironment(_environment))
188 return kErrorInvalidArgument;
190 if (isDebugServer(_arguments)) {
193 ps.redirectInputToNull();
194 ps.redirectOutputToConsole();
195 ps.redirectErrorToConsole();
197 if (!_stdFile[0].empty() && !ps.redirectInputToFile(_stdFile[0]))
198 return kErrorInvalidArgument;
199 if (!_stdFile[1].empty() && !ps.redirectOutputToFile(_stdFile[1]))
200 return kErrorInvalidArgument;
201 if (!_stdFile[2].empty() && !ps.redirectErrorToFile(_stdFile[2]))
202 return kErrorInvalidArgument;
205 _lastLaunchResult = ps.run();
206 if (_lastLaunchResult != kSuccess)
207 return _lastLaunchResult;
211 _processList.push_back(ps.pid());
213 DS2LOG(Debug,
"launched %s as process %" PRI_PID, _arguments[0].c_str(),