2004-09-11 12:59:30 +08:00
|
|
|
//===-- Process.cpp - Implement OS Process Concept --------------*- C++ -*-===//
|
2005-04-22 06:55:34 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2005-04-22 06:55:34 +08:00
|
|
|
//
|
2004-09-11 12:59:30 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2014-06-20 09:36:00 +08:00
|
|
|
// This file implements the operating system Process concept.
|
2004-09-11 12:59:30 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2017-06-06 19:49:48 +08:00
|
|
|
#include "llvm/Support/Process.h"
|
2017-10-12 04:12:09 +08:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2014-07-01 03:54:20 +08:00
|
|
|
#include "llvm/ADT/StringExtras.h"
|
2018-08-21 00:49:54 +08:00
|
|
|
#include "llvm/Config/config.h"
|
2020-02-11 23:17:15 +08:00
|
|
|
#include "llvm/Config/llvm-config.h"
|
|
|
|
#include "llvm/Support/CrashRecoveryContext.h"
|
2014-07-01 03:54:20 +08:00
|
|
|
#include "llvm/Support/FileSystem.h"
|
2015-03-24 02:07:13 +08:00
|
|
|
#include "llvm/Support/Path.h"
|
2014-07-01 03:54:20 +08:00
|
|
|
#include "llvm/Support/Program.h"
|
2004-09-11 12:59:30 +08:00
|
|
|
|
2020-11-12 21:31:57 +08:00
|
|
|
#include <stdlib.h> // for _Exit
|
[LLD][COFF] When using LLD-as-a-library, always prevent re-entrance on failures
This is a follow-up for D70378 (Cover usage of LLD as a library).
While debugging an intermittent failure on a bot, I recalled this scenario which
causes the issue:
1.When executing lld/test/ELF/invalid/symtab-sh-info.s L45, we reach
lld::elf::Obj-File::ObjFile() which goes straight into its base ELFFileBase(),
then ELFFileBase::init().
2.At that point fatal() is thrown in lld/ELF/InputFiles.cpp L381, leaving a
half-initialized ObjFile instance.
3.We then end up in lld::exitLld() and since we are running with LLD_IN_TEST, we
hapily restore the control flow to CrashRecoveryContext::RunSafely() then back
in lld::safeLldMain().
4.Before this patch, we called errorHandler().reset() just after, and this
attempted to reset the associated SpecificAlloc<ObjFile<ELF64LE>>. That tried
to free the half-initialized ObjFile instance, and more precisely its
ObjFile::dwarf member.
Sometimes that worked, sometimes it failed and was catched by the
CrashRecoveryContext. This scenario was the reason we called
errorHandler().reset() through a CrashRecoveryContext.
But in some rare cases, the above repro somehow corrupted the heap, creating a
stack overflow. When the CrashRecoveryContext's filter (that is,
__except (ExceptionFilter(GetExceptionInformation()))) tried to handle the
exception, it crashed again since the stack was exhausted -- and that took the
whole application down. That is the issue seen on the bot. Locally it happens
about 1 times out of 15.
Now this situation can happen anywhere in LLD. Since catching stack overflows is
not a reliable scenario ATM when using CrashRecoveryContext, we're now
preventing further re-entrance when such failures occur, by signaling
lld::SafeReturn::canRunAgain=false. When running with LLD_IN_TEST=2 (or above),
only one iteration will be executed, instead of two.
Differential Revision: https://reviews.llvm.org/D88348
2020-11-12 21:14:20 +08:00
|
|
|
|
2012-12-31 19:45:20 +08:00
|
|
|
using namespace llvm;
|
2004-09-11 12:59:30 +08:00
|
|
|
using namespace sys;
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//=== WARNING: Implementation here must contain only TRULY operating system
|
2005-04-22 06:55:34 +08:00
|
|
|
//=== independent code.
|
2004-09-11 12:59:30 +08:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
Reapply: [clang-cl] Always interpret the LIB env var as separated with semicolons
When cross compiling with clang-cl, clang splits the INCLUDE env
variable around semicolons (clang/lib/Driver/ToolChains/MSVC.cpp,
MSVCToolChain::AddClangSystemIncludeArgs) and lld splits the
LIB variable similarly (lld/COFF/Driver.cpp,
LinkerDriver::addLibSearchPaths). Therefore, the consensus for
cross compilation with clang-cl and lld-link seems to be to use
semicolons, despite path lists normally being separated by colons
on unix and EnvPathSeparator being set to that.
Therefore, handle the LIB variable similarly in Clang, when
handling lib file arguments when driving linking via Clang.
This fixes commands like "clang-cl test.c -Fetest.exe kernel32.lib" in
a cross compilation setting. Normally, most users call (lld-)link
directly, but meson happens to use this command syntax for
has_function() tests.
Reapply: Change Program.h to define procid_t as ::pid_t. When included
in lldb/unittests/Host/NativeProcessProtocolTest.cpp, it is included
after an lldb namespace containing an lldb::pid_t typedef, followed
later by a "using namespace lldb;". Previously, Program.h wasn't
included in this translation unit, but now it ends up included
transitively from Process.h.
Differential Revision: https://reviews.llvm.org/D88002
2020-09-21 04:19:12 +08:00
|
|
|
Optional<std::string>
|
|
|
|
Process::FindInEnvPath(StringRef EnvName, StringRef FileName, char Separator) {
|
|
|
|
return FindInEnvPath(EnvName, FileName, {}, Separator);
|
2017-10-12 04:12:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Optional<std::string> Process::FindInEnvPath(StringRef EnvName,
|
|
|
|
StringRef FileName,
|
Reapply: [clang-cl] Always interpret the LIB env var as separated with semicolons
When cross compiling with clang-cl, clang splits the INCLUDE env
variable around semicolons (clang/lib/Driver/ToolChains/MSVC.cpp,
MSVCToolChain::AddClangSystemIncludeArgs) and lld splits the
LIB variable similarly (lld/COFF/Driver.cpp,
LinkerDriver::addLibSearchPaths). Therefore, the consensus for
cross compilation with clang-cl and lld-link seems to be to use
semicolons, despite path lists normally being separated by colons
on unix and EnvPathSeparator being set to that.
Therefore, handle the LIB variable similarly in Clang, when
handling lib file arguments when driving linking via Clang.
This fixes commands like "clang-cl test.c -Fetest.exe kernel32.lib" in
a cross compilation setting. Normally, most users call (lld-)link
directly, but meson happens to use this command syntax for
has_function() tests.
Reapply: Change Program.h to define procid_t as ::pid_t. When included
in lldb/unittests/Host/NativeProcessProtocolTest.cpp, it is included
after an lldb namespace containing an lldb::pid_t typedef, followed
later by a "using namespace lldb;". Previously, Program.h wasn't
included in this translation unit, but now it ends up included
transitively from Process.h.
Differential Revision: https://reviews.llvm.org/D88002
2020-09-21 04:19:12 +08:00
|
|
|
ArrayRef<std::string> IgnoreList,
|
|
|
|
char Separator) {
|
2015-04-25 06:18:46 +08:00
|
|
|
assert(!path::is_absolute(FileName));
|
2014-07-01 03:54:20 +08:00
|
|
|
Optional<std::string> FoundPath;
|
|
|
|
Optional<std::string> OptPath = Process::GetEnv(EnvName);
|
|
|
|
if (!OptPath.hasValue())
|
|
|
|
return FoundPath;
|
|
|
|
|
Reapply: [clang-cl] Always interpret the LIB env var as separated with semicolons
When cross compiling with clang-cl, clang splits the INCLUDE env
variable around semicolons (clang/lib/Driver/ToolChains/MSVC.cpp,
MSVCToolChain::AddClangSystemIncludeArgs) and lld splits the
LIB variable similarly (lld/COFF/Driver.cpp,
LinkerDriver::addLibSearchPaths). Therefore, the consensus for
cross compilation with clang-cl and lld-link seems to be to use
semicolons, despite path lists normally being separated by colons
on unix and EnvPathSeparator being set to that.
Therefore, handle the LIB variable similarly in Clang, when
handling lib file arguments when driving linking via Clang.
This fixes commands like "clang-cl test.c -Fetest.exe kernel32.lib" in
a cross compilation setting. Normally, most users call (lld-)link
directly, but meson happens to use this command syntax for
has_function() tests.
Reapply: Change Program.h to define procid_t as ::pid_t. When included
in lldb/unittests/Host/NativeProcessProtocolTest.cpp, it is included
after an lldb namespace containing an lldb::pid_t typedef, followed
later by a "using namespace lldb;". Previously, Program.h wasn't
included in this translation unit, but now it ends up included
transitively from Process.h.
Differential Revision: https://reviews.llvm.org/D88002
2020-09-21 04:19:12 +08:00
|
|
|
const char EnvPathSeparatorStr[] = {Separator, '\0'};
|
2014-07-01 03:54:20 +08:00
|
|
|
SmallVector<StringRef, 8> Dirs;
|
|
|
|
SplitString(OptPath.getValue(), Dirs, EnvPathSeparatorStr);
|
|
|
|
|
2017-10-12 04:12:09 +08:00
|
|
|
for (StringRef Dir : Dirs) {
|
2014-07-01 03:54:20 +08:00
|
|
|
if (Dir.empty())
|
|
|
|
continue;
|
2017-10-12 04:12:09 +08:00
|
|
|
|
|
|
|
if (any_of(IgnoreList, [&](StringRef S) { return fs::equivalent(S, Dir); }))
|
|
|
|
continue;
|
2014-07-01 03:54:20 +08:00
|
|
|
|
|
|
|
SmallString<128> FilePath(Dir);
|
|
|
|
path::append(FilePath, FileName);
|
|
|
|
if (fs::exists(Twine(FilePath))) {
|
2020-01-29 03:23:46 +08:00
|
|
|
FoundPath = std::string(FilePath.str());
|
2014-07-01 03:54:20 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FoundPath;
|
|
|
|
}
|
|
|
|
|
2013-01-05 07:19:55 +08:00
|
|
|
|
2013-09-11 08:36:48 +08:00
|
|
|
#define COLOR(FGBG, CODE, BOLD) "\033[0;" BOLD FGBG CODE "m"
|
|
|
|
|
|
|
|
#define ALLCOLORS(FGBG,BOLD) {\
|
|
|
|
COLOR(FGBG, "0", BOLD),\
|
|
|
|
COLOR(FGBG, "1", BOLD),\
|
|
|
|
COLOR(FGBG, "2", BOLD),\
|
|
|
|
COLOR(FGBG, "3", BOLD),\
|
|
|
|
COLOR(FGBG, "4", BOLD),\
|
|
|
|
COLOR(FGBG, "5", BOLD),\
|
|
|
|
COLOR(FGBG, "6", BOLD),\
|
|
|
|
COLOR(FGBG, "7", BOLD)\
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char colorcodes[2][2][8][10] = {
|
|
|
|
{ ALLCOLORS("3",""), ALLCOLORS("3","1;") },
|
|
|
|
{ ALLCOLORS("4",""), ALLCOLORS("4","1;") }
|
|
|
|
};
|
|
|
|
|
2018-08-24 06:58:56 +08:00
|
|
|
// A CMake option controls wheter we emit core dumps by default. An application
|
|
|
|
// may disable core dumps by calling Process::PreventCoreFiles().
|
|
|
|
static bool coreFilesPrevented = !LLVM_ENABLE_CRASH_DUMPS;
|
2016-05-05 00:56:51 +08:00
|
|
|
|
2018-08-24 06:58:56 +08:00
|
|
|
bool Process::AreCoreFilesPrevented() { return coreFilesPrevented; }
|
2016-05-05 00:56:51 +08:00
|
|
|
|
2021-07-29 00:31:14 +08:00
|
|
|
[[noreturn]] void Process::Exit(int RetCode, bool NoCleanup) {
|
2020-02-11 23:17:15 +08:00
|
|
|
if (CrashRecoveryContext *CRC = CrashRecoveryContext::GetCurrent())
|
|
|
|
CRC->HandleExit(RetCode);
|
[LLD][COFF] When using LLD-as-a-library, always prevent re-entrance on failures
This is a follow-up for D70378 (Cover usage of LLD as a library).
While debugging an intermittent failure on a bot, I recalled this scenario which
causes the issue:
1.When executing lld/test/ELF/invalid/symtab-sh-info.s L45, we reach
lld::elf::Obj-File::ObjFile() which goes straight into its base ELFFileBase(),
then ELFFileBase::init().
2.At that point fatal() is thrown in lld/ELF/InputFiles.cpp L381, leaving a
half-initialized ObjFile instance.
3.We then end up in lld::exitLld() and since we are running with LLD_IN_TEST, we
hapily restore the control flow to CrashRecoveryContext::RunSafely() then back
in lld::safeLldMain().
4.Before this patch, we called errorHandler().reset() just after, and this
attempted to reset the associated SpecificAlloc<ObjFile<ELF64LE>>. That tried
to free the half-initialized ObjFile instance, and more precisely its
ObjFile::dwarf member.
Sometimes that worked, sometimes it failed and was catched by the
CrashRecoveryContext. This scenario was the reason we called
errorHandler().reset() through a CrashRecoveryContext.
But in some rare cases, the above repro somehow corrupted the heap, creating a
stack overflow. When the CrashRecoveryContext's filter (that is,
__except (ExceptionFilter(GetExceptionInformation()))) tried to handle the
exception, it crashed again since the stack was exhausted -- and that took the
whole application down. That is the issue seen on the bot. Locally it happens
about 1 times out of 15.
Now this situation can happen anywhere in LLD. Since catching stack overflows is
not a reliable scenario ATM when using CrashRecoveryContext, we're now
preventing further re-entrance when such failures occur, by signaling
lld::SafeReturn::canRunAgain=false. When running with LLD_IN_TEST=2 (or above),
only one iteration will be executed, instead of two.
Differential Revision: https://reviews.llvm.org/D88348
2020-11-12 21:14:20 +08:00
|
|
|
|
|
|
|
if (NoCleanup)
|
2021-05-22 04:50:01 +08:00
|
|
|
ExitNoCleanup(RetCode);
|
[LLD][COFF] When using LLD-as-a-library, always prevent re-entrance on failures
This is a follow-up for D70378 (Cover usage of LLD as a library).
While debugging an intermittent failure on a bot, I recalled this scenario which
causes the issue:
1.When executing lld/test/ELF/invalid/symtab-sh-info.s L45, we reach
lld::elf::Obj-File::ObjFile() which goes straight into its base ELFFileBase(),
then ELFFileBase::init().
2.At that point fatal() is thrown in lld/ELF/InputFiles.cpp L381, leaving a
half-initialized ObjFile instance.
3.We then end up in lld::exitLld() and since we are running with LLD_IN_TEST, we
hapily restore the control flow to CrashRecoveryContext::RunSafely() then back
in lld::safeLldMain().
4.Before this patch, we called errorHandler().reset() just after, and this
attempted to reset the associated SpecificAlloc<ObjFile<ELF64LE>>. That tried
to free the half-initialized ObjFile instance, and more precisely its
ObjFile::dwarf member.
Sometimes that worked, sometimes it failed and was catched by the
CrashRecoveryContext. This scenario was the reason we called
errorHandler().reset() through a CrashRecoveryContext.
But in some rare cases, the above repro somehow corrupted the heap, creating a
stack overflow. When the CrashRecoveryContext's filter (that is,
__except (ExceptionFilter(GetExceptionInformation()))) tried to handle the
exception, it crashed again since the stack was exhausted -- and that took the
whole application down. That is the issue seen on the bot. Locally it happens
about 1 times out of 15.
Now this situation can happen anywhere in LLD. Since catching stack overflows is
not a reliable scenario ATM when using CrashRecoveryContext, we're now
preventing further re-entrance when such failures occur, by signaling
lld::SafeReturn::canRunAgain=false. When running with LLD_IN_TEST=2 (or above),
only one iteration will be executed, instead of two.
Differential Revision: https://reviews.llvm.org/D88348
2020-11-12 21:14:20 +08:00
|
|
|
else
|
|
|
|
::exit(RetCode);
|
2020-02-11 23:17:15 +08:00
|
|
|
}
|
|
|
|
|
2004-09-11 12:59:30 +08:00
|
|
|
// Include the platform-specific parts of this class.
|
2004-12-27 14:15:29 +08:00
|
|
|
#ifdef LLVM_ON_UNIX
|
2005-01-10 07:29:00 +08:00
|
|
|
#include "Unix/Process.inc"
|
2004-12-27 14:15:29 +08:00
|
|
|
#endif
|
2018-04-29 08:45:03 +08:00
|
|
|
#ifdef _WIN32
|
2010-11-30 02:16:10 +08:00
|
|
|
#include "Windows/Process.inc"
|
2004-12-27 14:15:29 +08:00
|
|
|
#endif
|