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,12 +66,21 @@ 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);
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
+ });
74
84
75
85
startupinfo.cb = sizeof (startupinfo);
76
86
startupinfo.dwFlags |= STARTF_USESTDHANDLES;
@@ -81,6 +91,40 @@ 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 (act->GetFD ());
117
+ }
118
+ }
119
+ if (!UpdateProcThreadAttribute (
120
+ attributelist_up.get (), /* dwFlags=*/ 0 ,
121
+ PROC_THREAD_ATTRIBUTE_HANDLE_LIST, inherited_handles.data (),
122
+ inherited_handles.size (),
123
+ /* lpPreviousValue=*/ nullptr , /* lpReturnSize=*/ nullptr )) {
124
+ error = Status (::GetLastError (), eErrorTypeWin32);
125
+ return HostProcess ();
126
+ }
127
+
84
128
const char *hide_console_var =
85
129
getenv (" LLDB_LAUNCH_INFERIORS_WITHOUT_CONSOLE" );
86
130
if (hide_console_var &&
@@ -89,7 +133,8 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
89
133
startupinfo.wShowWindow = SW_HIDE;
90
134
}
91
135
92
- DWORD flags = CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;
136
+ DWORD flags = CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT |
137
+ EXTENDED_STARTUPINFO_PRESENT;
93
138
if (launch_info.GetFlags ().Test (eLaunchFlagDebug))
94
139
flags |= DEBUG_ONLY_THIS_PROCESS;
95
140
@@ -131,13 +176,6 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
131
176
::CloseHandle (pi.hThread);
132
177
}
133
178
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
179
if (!result)
142
180
return HostProcess ();
143
181
0 commit comments