Skip to content

Commit 17916b6

Browse files
committed
Merged with #100659
1 parent 7fb5b2e commit 17916b6

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

lldb/source/Host/posix/ProcessLauncherPosixFork.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ struct ForkLaunchInfo {
201201
execve(info.argv[0], const_cast<char *const *>(info.argv), info.envp);
202202

203203
#if defined(__linux__)
204-
if (errno == ETXTBSY) {
204+
for (int i = 0; i < 50; ++i) {
205205
// On android M and earlier we can get this error because the adb daemon
206206
// can hold a write handle on the executable even after it has finished
207207
// uploading it. This state lasts only a short time and happens only when
@@ -210,7 +210,13 @@ struct ForkLaunchInfo {
210210
// shell" command in the fork() child before it has had a chance to exec.)
211211
// Since this state should clear up quickly, wait a while and then give it
212212
// one more go.
213-
usleep(50000);
213+
// If `lldb-server platform` copies the executable in one thread and
214+
// launches gdbserver in another thread (fork+execve), the FD may stay
215+
// opened in the forked child process until execve() even if the first
216+
// thread closed the file. Let's wait a while.
217+
if (errno != ETXTBSY)
218+
break;
219+
usleep(100000);
214220
execve(info.argv[0], const_cast<char *const *>(info.argv), info.envp);
215221
}
216222
#endif

lldb/source/Host/windows/ProcessLauncherWindows.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,30 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
113113
// command line is not empty, its contents may be modified by CreateProcessW.
114114
WCHAR *pwcommandLine = wcommandLine.empty() ? nullptr : &wcommandLine[0];
115115

116-
BOOL result = ::CreateProcessW(
117-
wexecutable.c_str(), pwcommandLine, NULL, NULL, TRUE, flags, env_block,
118-
wworkingDirectory.size() == 0 ? NULL : wworkingDirectory.c_str(),
119-
&startupinfo, &pi);
116+
BOOL result;
117+
DWORD last_error = 0;
118+
// This is the workaround for the error "The process cannot access the file
119+
// because it is being used by another process". Note the executable file is
120+
// installed to the target by the process `lldb-server platform`, but launched
121+
// by the process `lldb-server gdbserver`. Sometimes system may block the file
122+
// for some time after copying.
123+
for (int i = 0; i < 50; ++i) {
124+
result = ::CreateProcessW(
125+
wexecutable.c_str(), pwcommandLine, NULL, NULL, TRUE, flags, env_block,
126+
wworkingDirectory.size() == 0 ? NULL : wworkingDirectory.c_str(),
127+
&startupinfo, &pi);
128+
if (!result) {
129+
last_error = ::GetLastError();
130+
if (last_error != ERROR_SHARING_VIOLATION)
131+
break;
132+
::Sleep(100);
133+
} else
134+
break;
135+
}
120136

121137
if (!result) {
122138
// Call GetLastError before we make any other system calls.
123-
error.SetError(::GetLastError(), eErrorTypeWin32);
139+
error.SetError(last_error, eErrorTypeWin32);
124140
// Note that error 50 ("The request is not supported") will occur if you
125141
// try debug a 64-bit inferior from a 32-bit LLDB.
126142
}

0 commit comments

Comments
 (0)