Skip to content

Commit

Permalink
Merged with #100659
Browse files Browse the repository at this point in the history
  • Loading branch information
slydiman committed Jul 29, 2024
1 parent 0870140 commit e69a04e
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 7 deletions.
10 changes: 8 additions & 2 deletions lldb/source/Host/posix/ProcessLauncherPosixFork.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ struct ForkLaunchInfo {
execve(info.argv[0], const_cast<char *const *>(info.argv), info.envp);

#if defined(__linux__)
if (errno == ETXTBSY) {
for (int i = 0; i < 50; ++i) {
// On android M and earlier we can get this error because the adb daemon
// can hold a write handle on the executable even after it has finished
// uploading it. This state lasts only a short time and happens only when
Expand All @@ -210,7 +210,13 @@ struct ForkLaunchInfo {
// shell" command in the fork() child before it has had a chance to exec.)
// Since this state should clear up quickly, wait a while and then give it
// one more go.
usleep(50000);
// If `lldb-server platform` copies the executable in one thread and
// launches gdbserver in another thread (fork+execve), the FD may stay
// opened in the forked child process until execve() even if the first
// thread closed the file. Let's wait a while.
if (errno != ETXTBSY)
break;
usleep(100000);
execve(info.argv[0], const_cast<char *const *>(info.argv), info.envp);
}
#endif
Expand Down
26 changes: 21 additions & 5 deletions lldb/source/Host/windows/ProcessLauncherWindows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,30 @@ ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
// command line is not empty, its contents may be modified by CreateProcessW.
WCHAR *pwcommandLine = wcommandLine.empty() ? nullptr : &wcommandLine[0];

BOOL result = ::CreateProcessW(
wexecutable.c_str(), pwcommandLine, NULL, NULL, TRUE, flags, env_block,
wworkingDirectory.size() == 0 ? NULL : wworkingDirectory.c_str(),
&startupinfo, &pi);
BOOL result;
DWORD last_error = 0;
// This is the workaround for the error "The process cannot access the file
// because it is being used by another process". Note the executable file is
// installed to the target by the process `lldb-server platform`, but launched
// by the process `lldb-server gdbserver`. Sometimes system may block the file
// for some time after copying.
for (int i = 0; i < 50; ++i) {
result = ::CreateProcessW(
wexecutable.c_str(), pwcommandLine, NULL, NULL, TRUE, flags, env_block,
wworkingDirectory.size() == 0 ? NULL : wworkingDirectory.c_str(),
&startupinfo, &pi);
if (!result) {
last_error = ::GetLastError();
if (last_error != ERROR_SHARING_VIOLATION)
break;
::Sleep(100);
} else
break;
}

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

0 comments on commit e69a04e

Please sign in to comment.