blob: d42102570356566fed33dcb282def98762798ab4 [file] [log] [blame]
Zachary Turner35ed1322014-07-28 16:45:18 +00001//===-- ProcessWindows.cpp --------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// Windows includes
11#include "lldb/Host/windows/windows.h"
12
13// C++ Includes
14// Other libraries and framework includes
15#include "lldb/Core/Module.h"
16#include "lldb/Core/PluginManager.h"
17#include "lldb/Core/State.h"
18#include "lldb/Host/Host.h"
19#include "lldb/Symbol/ObjectFile.h"
20#include "lldb/Target/DynamicLoader.h"
21#include "lldb/Target/Target.h"
22
23#include "ProcessWindows.h"
24
25using namespace lldb;
26using namespace lldb_private;
27
Zachary Turnerf490bec2014-08-04 23:31:21 +000028namespace
29{
30HANDLE
31GetStdioHandle(ProcessLaunchInfo &launch_info, int fd)
32{
33 const ProcessLaunchInfo::FileAction *action = launch_info.GetFileActionForFD(fd);
34 if (action == nullptr)
35 return NULL;
36 SECURITY_ATTRIBUTES secattr = {0};
37 secattr.nLength = sizeof(SECURITY_ATTRIBUTES);
38 secattr.bInheritHandle = TRUE;
39
40 const char *path = action->GetPath();
41 DWORD access = 0;
42 DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE;
43 DWORD create = 0;
44 DWORD flags = 0;
45 if (fd == STDIN_FILENO)
46 {
47 access = GENERIC_READ;
48 create = OPEN_EXISTING;
49 flags = FILE_ATTRIBUTE_READONLY;
50 }
51 if (fd == STDOUT_FILENO || fd == STDERR_FILENO)
52 {
53 access = GENERIC_WRITE;
54 create = CREATE_ALWAYS;
55 if (fd == STDERR_FILENO)
56 flags = FILE_FLAG_WRITE_THROUGH;
57 }
58
59 HANDLE result = ::CreateFile(path, access, share, &secattr, create, flags, NULL);
60 return (result == INVALID_HANDLE_VALUE) ? NULL : result;
61}
62}
63
Zachary Turner35ed1322014-07-28 16:45:18 +000064//------------------------------------------------------------------------------
65// Static functions.
66
67ProcessSP
68ProcessWindows::CreateInstance(Target &target, Listener &listener, const FileSpec *)
69{
70 return ProcessSP(new ProcessWindows(target, listener));
71}
72
73void
74ProcessWindows::Initialize()
75{
76 static bool g_initialized = false;
77
78 if (!g_initialized)
79 {
80 g_initialized = true;
81 PluginManager::RegisterPlugin(GetPluginNameStatic(),
82 GetPluginDescriptionStatic(),
83 CreateInstance);
84 }
85}
86
87//------------------------------------------------------------------------------
88// Constructors and destructors.
89
90ProcessWindows::ProcessWindows(Target& target, Listener &listener)
91 : lldb_private::Process(target, listener)
92{
93}
94
95void
96ProcessWindows::Terminate()
97{
98}
99
100lldb_private::ConstString
101ProcessWindows::GetPluginNameStatic()
102{
103 static ConstString g_name("windows");
104 return g_name;
105}
106
107const char *
108ProcessWindows::GetPluginDescriptionStatic()
109{
110 return "Process plugin for Windows";
111}
112
113
114bool
115ProcessWindows::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
116{
117 new_thread_list = old_thread_list;
118 return new_thread_list.GetSize(false) > 0;
119}
120
121Error
122ProcessWindows::DoLaunch(Module *exe_module,
123 ProcessLaunchInfo &launch_info)
124{
125 std::string executable;
126 std::string commandLine;
127 std::vector<char> environment;
128 STARTUPINFO startupinfo = {0};
129 PROCESS_INFORMATION pi = {0};
Zachary Turnerf490bec2014-08-04 23:31:21 +0000130
131 HANDLE stdin_handle = GetStdioHandle(launch_info, STDIN_FILENO);
132 HANDLE stdout_handle = GetStdioHandle(launch_info, STDOUT_FILENO);
133 HANDLE stderr_handle = GetStdioHandle(launch_info, STDERR_FILENO);
134
Zachary Turner35ed1322014-07-28 16:45:18 +0000135 startupinfo.cb = sizeof(startupinfo);
Zachary Turnerf490bec2014-08-04 23:31:21 +0000136 startupinfo.dwFlags |= STARTF_USESTDHANDLES;
137 startupinfo.hStdError = stderr_handle;
138 startupinfo.hStdInput = stdin_handle;
139 startupinfo.hStdOutput = stdout_handle;
140
Zachary Turner35ed1322014-07-28 16:45:18 +0000141 executable = launch_info.GetExecutableFile().GetPath();
142 launch_info.GetArguments().GetQuotedCommandString(commandLine);
Zachary Turnerf490bec2014-08-04 23:31:21 +0000143 BOOL result = ::CreateProcessA(executable.c_str(), const_cast<char *>(commandLine.c_str()), NULL, NULL, TRUE,
144 CREATE_NEW_CONSOLE, NULL, launch_info.GetWorkingDirectory(), &startupinfo, &pi);
145 if (result)
146 {
147 ::CloseHandle(pi.hProcess);
148 ::CloseHandle(pi.hThread);
149 }
150
151 if (stdin_handle)
152 ::CloseHandle(stdin_handle);
153 if (stdout_handle)
154 ::CloseHandle(stdout_handle);
155 if (stderr_handle)
156 ::CloseHandle(stderr_handle);
157
Zachary Turner35ed1322014-07-28 16:45:18 +0000158 Error error;
159 if (!result)
160 error.SetErrorToErrno();
161 return error;
162}
163
164Error
165ProcessWindows::DoResume()
166{
167 Error error;
168 return error;
169}
170
171
172//------------------------------------------------------------------------------
173// ProcessInterface protocol.
174
175lldb_private::ConstString
176ProcessWindows::GetPluginName()
177{
178 return GetPluginNameStatic();
179}
180
181uint32_t
182ProcessWindows::GetPluginVersion()
183{
184 return 1;
185}
186
187void
188ProcessWindows::GetPluginCommandHelp(const char *command, Stream *strm)
189{
190}
191
192Error
193ProcessWindows::ExecutePluginCommand(Args &command, Stream *strm)
194{
195 return Error(1, eErrorTypeGeneric);
196}
197
198Log *
199ProcessWindows::EnablePluginLogging(Stream *strm, Args &command)
200{
201 return NULL;
202}
203
204Error
205ProcessWindows::DoDetach(bool keep_stopped)
206{
207 Error error;
208 error.SetErrorString("Detaching from processes is not currently supported on Windows.");
209 return error;
210}
211
212Error
213ProcessWindows::DoDestroy()
214{
215 Error error;
216 error.SetErrorString("Destroying processes is not currently supported on Windows.");
217 return error;
218}
219
220void
221ProcessWindows::RefreshStateAfterStop()
222{
223}
224
225bool
226ProcessWindows::IsAlive()
227{
228 return false;
229}
230
231size_t
232ProcessWindows::DoReadMemory(lldb::addr_t vm_addr,
233 void *buf,
234 size_t size,
235 Error &error)
236{
237 return 0;
238}
239
240
241bool
242ProcessWindows::CanDebug(Target &target, bool plugin_specified_by_name)
243{
244 if (plugin_specified_by_name)
245 return true;
246
247 // For now we are just making sure the file exists for a given module
248 ModuleSP exe_module_sp(target.GetExecutableModule());
249 if (exe_module_sp.get())
250 return exe_module_sp->GetFileSpec().Exists();
251 return false;
252}
253