diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-06-09 00:53:21 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-06-09 00:53:21 +0000 |
commit | 2ad6d48b0c631d7fa8416c07f8b47f167cfd2fd8 (patch) | |
tree | 3d828acb25a67cb8ec584877faa300c9c8ae2289 /llvm/lib | |
parent | 6d1d27542fd66465f5e1e3e4248910b15f47a8b2 (diff) | |
download | bcm5719-llvm-2ad6d48b0c631d7fa8416c07f8b47f167cfd2fd8.tar.gz bcm5719-llvm-2ad6d48b0c631d7fa8416c07f8b47f167cfd2fd8.zip |
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
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Support/Signals.cpp | 34 | ||||
-rw-r--r-- | llvm/lib/Support/Unix/Signals.inc | 9 | ||||
-rw-r--r-- | llvm/lib/Support/Windows/Signals.inc | 9 |
3 files changed, 37 insertions, 15 deletions
diff --git a/llvm/lib/Support/Signals.cpp b/llvm/lib/Support/Signals.cpp index 3dc6b7c99d0..e5e38f59c04 100644 --- a/llvm/lib/Support/Signals.cpp +++ b/llvm/lib/Support/Signals.cpp @@ -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); diff --git a/llvm/lib/Support/Unix/Signals.inc b/llvm/lib/Support/Unix/Signals.inc index b49b8aae4ff..117d4e8bcb5 100644 --- a/llvm/lib/Support/Unix/Signals.inc +++ b/llvm/lib/Support/Unix/Signals.inc @@ -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) diff --git a/llvm/lib/Support/Windows/Signals.inc b/llvm/lib/Support/Windows/Signals.inc index 3a0e5569f93..834f50ad10e 100644 --- a/llvm/lib/Support/Windows/Signals.inc +++ b/llvm/lib/Support/Windows/Signals.inc @@ -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(); |