10
10
#include " lldb/Host/HostProcess.h"
11
11
#include " lldb/Host/ProcessLaunchInfo.h"
12
12
13
+ #include " llvm/ADT/ScopeExit.h"
13
14
#include " llvm/ADT/SmallVector.h"
14
15
#include " llvm/Support/ConvertUTF.h"
15
16
#include " llvm/Support/Program.h"
@@ -65,14 +66,23 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
65
66
66
67
std::string executable;
67
68
std::vector<char > environment;
68
- STARTUPINFO startupinfo = {};
69
+ STARTUPINFOEX startupinfoex = {};
70
+ STARTUPINFO &startupinfo = startupinfoex.StartupInfo ;
69
71
PROCESS_INFORMATION pi = {};
70
72
71
73
HANDLE stdin_handle = GetStdioHandle (launch_info, STDIN_FILENO);
72
74
HANDLE stdout_handle = GetStdioHandle (launch_info, STDOUT_FILENO);
73
75
HANDLE stderr_handle = GetStdioHandle (launch_info, STDERR_FILENO);
74
-
75
- startupinfo.cb = sizeof (startupinfo);
76
+ auto close_handles = llvm::make_scope_exit ([&] {
77
+ if (stdin_handle)
78
+ ::CloseHandle (stdin_handle);
79
+ if (stdout_handle)
80
+ ::CloseHandle (stdout_handle);
81
+ if (stderr_handle)
82
+ ::CloseHandle (stderr_handle);
83
+ });
84
+
85
+ startupinfo.cb = sizeof (startupinfoex);
76
86
startupinfo.dwFlags |= STARTF_USESTDHANDLES;
77
87
startupinfo.hStdError =
78
88
stderr_handle ? stderr_handle : ::GetStdHandle (STD_ERROR_HANDLE);
@@ -81,6 +91,41 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
81
91
startupinfo.hStdOutput =
82
92
stdout_handle ? stdout_handle : ::GetStdHandle (STD_OUTPUT_HANDLE);
83
93
94
+ size_t attributelist_size = 0 ;
95
+ InitializeProcThreadAttributeList (/* lpAttributeList=*/ nullptr ,
96
+ /* dwAttributeCount=*/ 1 , /* dwFlags=*/ 0 ,
97
+ &attributelist_size);
98
+
99
+ startupinfoex.lpAttributeList =
100
+ static_cast <LPPROC_THREAD_ATTRIBUTE_LIST>(malloc (attributelist_size));
101
+ auto free_attributelist =
102
+ llvm::make_scope_exit ([&] { free (startupinfoex.lpAttributeList ); });
103
+ if (!InitializeProcThreadAttributeList (startupinfoex.lpAttributeList ,
104
+ /* dwAttributeCount=*/ 1 , /* dwFlags=*/ 0 ,
105
+ &attributelist_size)) {
106
+ error = Status (::GetLastError (), eErrorTypeWin32);
107
+ return HostProcess ();
108
+ }
109
+ auto delete_attributelist = llvm::make_scope_exit (
110
+ [&] { DeleteProcThreadAttributeList (startupinfoex.lpAttributeList ); });
111
+ std::vector<HANDLE> inherited_handles;
112
+ for (size_t i = 0 ; i < launch_info.GetNumFileActions (); ++i) {
113
+ const FileAction *act = launch_info.GetFileActionAtIndex (i);
114
+ if (act->GetAction () == FileAction::eFileActionDuplicate &&
115
+ act->GetFD () == act->GetActionArgument ())
116
+ inherited_handles.push_back (reinterpret_cast <HANDLE>(act->GetFD ()));
117
+ }
118
+ if (!inherited_handles.empty ()) {
119
+ if (!UpdateProcThreadAttribute (
120
+ startupinfoex.lpAttributeList , /* dwFlags=*/ 0 ,
121
+ PROC_THREAD_ATTRIBUTE_HANDLE_LIST, inherited_handles.data (),
122
+ inherited_handles.size () * sizeof (HANDLE),
123
+ /* lpPreviousValue=*/ nullptr , /* lpReturnSize=*/ nullptr )) {
124
+ error = Status (::GetLastError (), eErrorTypeWin32);
125
+ return HostProcess ();
126
+ }
127
+ }
128
+
84
129
const char *hide_console_var =
85
130
getenv (" LLDB_LAUNCH_INFERIORS_WITHOUT_CONSOLE" );
86
131
if (hide_console_var &&
@@ -89,7 +134,8 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
89
134
startupinfo.wShowWindow = SW_HIDE;
90
135
}
91
136
92
- DWORD flags = CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;
137
+ DWORD flags = CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT |
138
+ EXTENDED_STARTUPINFO_PRESENT;
93
139
if (launch_info.GetFlags ().Test (eLaunchFlagDebug))
94
140
flags |= DEBUG_ONLY_THIS_PROCESS;
95
141
@@ -116,7 +162,7 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
116
162
BOOL result = ::CreateProcessW (
117
163
wexecutable.c_str (), pwcommandLine, NULL , NULL , TRUE , flags, env_block,
118
164
wworkingDirectory.size () == 0 ? NULL : wworkingDirectory.c_str (),
119
- &startupinfo , &pi);
165
+ reinterpret_cast <STARTUPINFO *>(&startupinfoex) , &pi);
120
166
121
167
if (!result) {
122
168
// Call GetLastError before we make any other system calls.
@@ -131,13 +177,6 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
131
177
::CloseHandle (pi.hThread);
132
178
}
133
179
134
- if (stdin_handle)
135
- ::CloseHandle (stdin_handle);
136
- if (stdout_handle)
137
- ::CloseHandle (stdout_handle);
138
- if (stderr_handle)
139
- ::CloseHandle (stderr_handle);
140
-
141
180
if (!result)
142
181
return HostProcess ();
143
182
0 commit comments