Search for llvm-symbolizer binary in the same directory as argv[0], before

looking for it along $PATH. This allows installs of LLVM tools outside of
$PATH to find the symbolizer and produce pretty backtraces if they crash.

llvm-svn: 272232
This commit is contained in:
Richard Smith 2016-06-09 00:53:21 +00:00
parent 6d1d27542f
commit 2ad6d48b0c
41 changed files with 87 additions and 73 deletions

View File

@ -38,8 +38,14 @@ namespace sys {
/// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the
/// process, print a stack trace and then exit.
/// @brief Print a stack trace if a fatal signal occurs.
void PrintStackTraceOnErrorSignal(bool DisableCrashReporting = false);
/// \brief Print a stack trace if a fatal signal occurs.
/// \param Argv0 the current binary name, used to find the symbolizer
/// relative to the current binary before searching $PATH; can be
/// StringRef(), in which case we will only search $PATH.
/// \param DisableCrashReporting if \c true, disable the normal crash
/// reporting mechanisms on the underlying operating system.
void PrintStackTraceOnErrorSignal(StringRef Argv0,
bool DisableCrashReporting = false);
/// Disable all system dialog boxes that appear when the process crashes.
void DisableSystemDialogsOnCrash();

View File

@ -62,28 +62,40 @@ static FormattedNumber format_ptr(void *PC) {
return format_hex((uint64_t)PC, PtrWidth);
}
static bool printSymbolizedStackTrace(void **StackTrace, int Depth,
static bool printSymbolizedStackTrace(StringRef Argv0,
void **StackTrace, int Depth,
llvm::raw_ostream &OS)
LLVM_ATTRIBUTE_USED;
/// Helper that launches llvm-symbolizer and symbolizes a backtrace.
static bool printSymbolizedStackTrace(void **StackTrace, int Depth,
static bool printSymbolizedStackTrace(StringRef Argv0,
void **StackTrace, int Depth,
llvm::raw_ostream &OS) {
// Don't recursively invoke the llvm-symbolizer binary.
if (Argv0.find("llvm-symbolizer") != std::string::npos)
return false;
// FIXME: Subtract necessary number from StackTrace entries to turn return addresses
// into actual instruction addresses.
// Use llvm-symbolizer tool to symbolize the stack traces.
ErrorOr<std::string> LLVMSymbolizerPathOrErr =
sys::findProgramByName("llvm-symbolizer");
// Use llvm-symbolizer tool to symbolize the stack traces. First look for it
// alongside our binary, then in $PATH.
ErrorOr<std::string> LLVMSymbolizerPathOrErr = std::error_code();
if (!Argv0.empty()) {
StringRef Parent = llvm::sys::path::parent_path(Argv0);
if (!Parent.empty())
LLVMSymbolizerPathOrErr = sys::findProgramByName("llvm-symbolizer", Parent);
}
if (!LLVMSymbolizerPathOrErr)
LLVMSymbolizerPathOrErr = sys::findProgramByName("llvm-symbolizer");
if (!LLVMSymbolizerPathOrErr)
return false;
const std::string &LLVMSymbolizerPath = *LLVMSymbolizerPathOrErr;
// We don't know argv0 or the address of main() at this point, but try
// to guess it anyway (it's possible on some platforms).
std::string MainExecutableName = sys::fs::getMainExecutable(nullptr, nullptr);
if (MainExecutableName.empty() ||
MainExecutableName.find("llvm-symbolizer") != std::string::npos)
return false;
// If we don't know argv0 or the address of main() at this point, try
// to guess it anyway (it's possible on some platforms).
std::string MainExecutableName =
Argv0.empty() ? sys::fs::getMainExecutable(nullptr, nullptr)
: (std::string)Argv0;
BumpPtrAllocator Allocator;
StringSaver StrPool(Allocator);
std::vector<const char *> Modules(Depth, nullptr);

View File

@ -68,6 +68,8 @@ static void (*InterruptFunction)() = nullptr;
static ManagedStatic<std::vector<std::string>> FilesToRemove;
static StringRef Argv0;
// IntSigs - Signals that represent requested termination. There's no bug
// or failure, or if there is, it's not our direct responsibility. For whatever
// reason, our continued execution is no longer desirable.
@ -408,7 +410,7 @@ void llvm::sys::PrintStackTrace(raw_ostream &OS) {
if (!depth)
return;
if (printSymbolizedStackTrace(StackTrace, depth, OS))
if (printSymbolizedStackTrace(Argv0, StackTrace, depth, OS))
return;
#if HAVE_DLFCN_H && __GNUG__
int width = 0;
@ -471,7 +473,10 @@ void llvm::sys::DisableSystemDialogsOnCrash() {}
/// PrintStackTraceOnErrorSignal - When an error signal (such as SIGABRT or
/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
void llvm::sys::PrintStackTraceOnErrorSignal(bool DisableCrashReporting) {
void llvm::sys::PrintStackTraceOnErrorSignal(StringRef Argv0,
bool DisableCrashReporting) {
::Argv0 = Argv0;
AddSignalHandler(PrintStackTraceSignalHandler, nullptr);
#if defined(__APPLE__) && defined(ENABLE_CRASH_OVERRIDES)

View File

@ -206,6 +206,8 @@ static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL;
static CRITICAL_SECTION CriticalSection;
static bool CriticalSectionInitialized = false;
static StringRef Argv0;
enum {
#if defined(_M_X64)
NativeMachineType = IMAGE_FILE_MACHINE_AMD64
@ -240,7 +242,7 @@ static bool printStackTraceWithLLVMSymbolizer(llvm::raw_ostream &OS,
break;
}
return printSymbolizedStackTrace(&StackTrace[0], Depth, OS);
return printSymbolizedStackTrace(Argv0, &StackTrace[0], Depth, OS);
}
namespace {
@ -496,7 +498,10 @@ void sys::DisableSystemDialogsOnCrash() {
/// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or
/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
void sys::PrintStackTraceOnErrorSignal(bool DisableCrashReporting) {
void sys::PrintStackTraceOnErrorSignal(StringRef Argv0,
bool DisableCrashReporting) {
::Argv0 = Argv0;
if (DisableCrashReporting || getenv("LLVM_DISABLE_CRASH_REPORT"))
Process::PreventCoreFiles();

View File

@ -113,7 +113,7 @@ void initializePollyPasses(llvm::PassRegistry &Registry);
int main(int argc, char **argv) {
#ifndef DEBUG_BUGPOINT
llvm::sys::PrintStackTraceOnErrorSignal();
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
llvm::PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
#endif

View File

@ -237,7 +237,7 @@ void llvm::dsymutil::exitDsymutil(int ExitStatus) {
}
int main(int argc, char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal();
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
llvm::PrettyStackTraceProgram StackPrinter(argc, argv);
llvm::llvm_shutdown_obj Shutdown;
LinkOptions Options;

View File

@ -202,7 +202,7 @@ static void DiagnosticHandler(const DiagnosticInfo &DI, void *Context) {
// main - Entry point for the llc compiler.
//
int main(int argc, char **argv) {
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
// Enable debug stream buffering.

View File

@ -365,7 +365,7 @@ CodeGenOpt::Level getOptLevel() {
// main Driver function
//
int main(int argc, char **argv, char * const *envp) {
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
atexit(llvm_shutdown); // Call llvm_shutdown() on exit.

View File

@ -773,7 +773,7 @@ static int ranlib_main() {
int main(int argc, char **argv) {
ToolName = argv[0];
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.

View File

@ -89,7 +89,7 @@ static void WriteOutputFile(const Module *M) {
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
LLVMContext Context;
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.

View File

@ -915,7 +915,7 @@ static int AnalyzeBitcode() {
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
cl::ParseCommandLineOptions(argc, argv, "llvm-bcanalyzer file analyzer\n");

View File

@ -26,11 +26,8 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include <functional>
#include <system_error>
@ -240,11 +237,6 @@ std::unique_ptr<CoverageMapping> CodeCoverageTool::load() {
}
int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
cl::opt<std::string, true> ObjectFilename(
cl::Positional, cl::Required, cl::location(this->ObjectFilename),
cl::desc("Covered executable or object file."));

View File

@ -11,9 +11,6 @@
#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/raw_ostream.h"
#include <functional>
#include <system_error>
@ -22,10 +19,6 @@ using namespace llvm;
using namespace object;
int convertForTestingMain(int argc, const char *argv[]) {
sys::PrintStackTraceOnErrorSignal();
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
cl::opt<std::string> InputSourceFile(cl::Positional, cl::Required,
cl::desc("<Source file>"));

View File

@ -16,10 +16,7 @@
#include "llvm/Support/Errc.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/GCOV.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include <system_error>
using namespace llvm;
@ -85,11 +82,6 @@ static void reportCoverage(StringRef SourceFile, StringRef ObjectDir,
}
int gcovMain(int argc, const char *argv[]) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
cl::list<std::string> SourceFiles(cl::Positional, cl::OneOrMore,
cl::desc("SOURCEFILE"));

View File

@ -14,8 +14,11 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/raw_ostream.h"
#include <string>
@ -51,6 +54,11 @@ static int versionMain(int argc, const char *argv[]) {
}
int main(int argc, const char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
// If argv[0] is or ends with 'gcov', always be gcov compatible
if (sys::path::stem(argv[0]).endswith_lower("gcov"))
return gcovMain(argc, argv);

View File

@ -525,7 +525,7 @@ static void dumpInput(StringRef File) {
}
int main(int argc, const char *argv[]) {
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y;

View File

@ -134,7 +134,7 @@ static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) {
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
LLVMContext Context;

View File

@ -146,7 +146,7 @@ static std::vector<std::string> expandBundle(const std::string &InputPath) {
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.

View File

@ -102,7 +102,7 @@ static cl::opt<bool> PreserveAssemblyUseListOrder(
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
LLVMContext Context;

View File

@ -179,7 +179,7 @@ InputFilename(cl::Positional, cl::desc("<input IR file>"),
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.

View File

@ -335,7 +335,7 @@ static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L,
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
LLVMContext Context;

View File

@ -691,7 +691,7 @@ private:
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.

View File

@ -369,7 +369,7 @@ static int AssembleInput(const char *ProgName, const Target *TheTarget,
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.

View File

@ -208,7 +208,7 @@ static void parseMCMarkup(StringRef Filename) {
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.

View File

@ -1347,7 +1347,7 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.

View File

@ -1736,7 +1736,7 @@ static void DumpInput(StringRef file) {
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.

View File

@ -433,7 +433,7 @@ static void dumpInput(StringRef Path) {
int main(int argc_, const char *argv_[]) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv_[0]);
PrettyStackTraceProgram X(argc_, argv_);
ExitOnErr.setBanner("llvm-pdbdump: ");

View File

@ -518,7 +518,7 @@ static int show_main(int argc, const char *argv[]) {
int main(int argc, const char *argv[]) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.

View File

@ -487,7 +487,7 @@ static void dumpInput(StringRef File) {
}
int main(int argc, const char *argv[]) {
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y;

View File

@ -726,7 +726,7 @@ static int linkAndVerify() {
}
int main(int argc, char **argv) {
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
ProgramName = argv[0];

View File

@ -806,7 +806,7 @@ static void printFileSectionSizes(StringRef file) {
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.

View File

@ -140,7 +140,7 @@ static bool parseCommand(StringRef InputString, bool &IsData,
int main(int argc, char **argv) {
// Print stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.

View File

@ -48,7 +48,7 @@ cl::opt<std::string> InputFilename(cl::Positional, cl::desc("<input file>"),
int main(int argc, char *argv[]) {
cl::ParseCommandLineOptions(argc, argv);
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.

View File

@ -327,7 +327,7 @@ void initializePollyPasses(llvm::PassRegistry &Registry);
// main for opt
//
int main(int argc, char **argv) {
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
llvm::PrettyStackTraceProgram X(argc, argv);
// Enable debug stream buffering.

View File

@ -1197,7 +1197,7 @@ private:
int main(int argc, char **argv) {
// Print stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.

View File

@ -526,7 +526,7 @@ static void reverseUseLists(Module &M) {
}
int main(int argc, char **argv) {
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
llvm::PrettyStackTraceProgram X(argc, argv);
// Enable debug stream buffering.

View File

@ -79,7 +79,7 @@ static int convertYAML(yaml::Input &YIn, raw_ostream &Out,
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv);
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.

View File

@ -1306,7 +1306,7 @@ static void DumpCommandLine(int argc, char **argv) {
}
int main(int argc, char **argv) {
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
cl::ParseCommandLineOptions(argc, argv);

View File

@ -296,7 +296,7 @@ static StringRef ExceptionCodeToString(DWORD ExceptionCode) {
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.

View File

@ -179,7 +179,7 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
}
int main(int argc, char **argv) {
sys::PrintStackTraceOnErrorSignal();
sys::PrintStackTraceOnErrorSignal(argv[0]);
PrettyStackTraceProgram X(argc, argv);
cl::ParseCommandLineOptions(argc, argv);

View File

@ -22,7 +22,8 @@
const char *TestMainArgv0;
int main(int argc, char **argv) {
llvm::sys::PrintStackTraceOnErrorSignal(true /* Disable crash reporting */);
llvm::sys::PrintStackTraceOnErrorSignal(argv[0],
true /* Disable crash reporting */);
testing::InitGoogleTest(&argc, argv);
llvm::cl::ParseCommandLineOptions(argc, argv);