Skip to content

Commit 2ad6d48

Browse files
committed
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
1 parent 6d1d275 commit 2ad6d48

File tree

41 files changed

+87
-73
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+87
-73
lines changed

llvm/include/llvm/Support/Signals.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,14 @@ namespace sys {
3838

3939
/// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the
4040
/// process, print a stack trace and then exit.
41-
/// @brief Print a stack trace if a fatal signal occurs.
42-
void PrintStackTraceOnErrorSignal(bool DisableCrashReporting = false);
41+
/// \brief Print a stack trace if a fatal signal occurs.
42+
/// \param Argv0 the current binary name, used to find the symbolizer
43+
/// relative to the current binary before searching $PATH; can be
44+
/// StringRef(), in which case we will only search $PATH.
45+
/// \param DisableCrashReporting if \c true, disable the normal crash
46+
/// reporting mechanisms on the underlying operating system.
47+
void PrintStackTraceOnErrorSignal(StringRef Argv0,
48+
bool DisableCrashReporting = false);
4349

4450
/// Disable all system dialog boxes that appear when the process crashes.
4551
void DisableSystemDialogsOnCrash();

llvm/lib/Support/Signals.cpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,28 +62,40 @@ static FormattedNumber format_ptr(void *PC) {
6262
return format_hex((uint64_t)PC, PtrWidth);
6363
}
6464

65-
static bool printSymbolizedStackTrace(void **StackTrace, int Depth,
65+
static bool printSymbolizedStackTrace(StringRef Argv0,
66+
void **StackTrace, int Depth,
6667
llvm::raw_ostream &OS)
6768
LLVM_ATTRIBUTE_USED;
6869

6970
/// Helper that launches llvm-symbolizer and symbolizes a backtrace.
70-
static bool printSymbolizedStackTrace(void **StackTrace, int Depth,
71+
static bool printSymbolizedStackTrace(StringRef Argv0,
72+
void **StackTrace, int Depth,
7173
llvm::raw_ostream &OS) {
74+
// Don't recursively invoke the llvm-symbolizer binary.
75+
if (Argv0.find("llvm-symbolizer") != std::string::npos)
76+
return false;
77+
7278
// FIXME: Subtract necessary number from StackTrace entries to turn return addresses
7379
// into actual instruction addresses.
74-
// Use llvm-symbolizer tool to symbolize the stack traces.
75-
ErrorOr<std::string> LLVMSymbolizerPathOrErr =
76-
sys::findProgramByName("llvm-symbolizer");
80+
// Use llvm-symbolizer tool to symbolize the stack traces. First look for it
81+
// alongside our binary, then in $PATH.
82+
ErrorOr<std::string> LLVMSymbolizerPathOrErr = std::error_code();
83+
if (!Argv0.empty()) {
84+
StringRef Parent = llvm::sys::path::parent_path(Argv0);
85+
if (!Parent.empty())
86+
LLVMSymbolizerPathOrErr = sys::findProgramByName("llvm-symbolizer", Parent);
87+
}
88+
if (!LLVMSymbolizerPathOrErr)
89+
LLVMSymbolizerPathOrErr = sys::findProgramByName("llvm-symbolizer");
7790
if (!LLVMSymbolizerPathOrErr)
7891
return false;
7992
const std::string &LLVMSymbolizerPath = *LLVMSymbolizerPathOrErr;
80-
// We don't know argv0 or the address of main() at this point, but try
81-
// to guess it anyway (it's possible on some platforms).
82-
std::string MainExecutableName = sys::fs::getMainExecutable(nullptr, nullptr);
83-
if (MainExecutableName.empty() ||
84-
MainExecutableName.find("llvm-symbolizer") != std::string::npos)
85-
return false;
8693

94+
// If we don't know argv0 or the address of main() at this point, try
95+
// to guess it anyway (it's possible on some platforms).
96+
std::string MainExecutableName =
97+
Argv0.empty() ? sys::fs::getMainExecutable(nullptr, nullptr)
98+
: (std::string)Argv0;
8799
BumpPtrAllocator Allocator;
88100
StringSaver StrPool(Allocator);
89101
std::vector<const char *> Modules(Depth, nullptr);

llvm/lib/Support/Unix/Signals.inc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ static void (*InterruptFunction)() = nullptr;
6868

6969
static ManagedStatic<std::vector<std::string>> FilesToRemove;
7070

71+
static StringRef Argv0;
72+
7173
// IntSigs - Signals that represent requested termination. There's no bug
7274
// or failure, or if there is, it's not our direct responsibility. For whatever
7375
// reason, our continued execution is no longer desirable.
@@ -408,7 +410,7 @@ void llvm::sys::PrintStackTrace(raw_ostream &OS) {
408410
if (!depth)
409411
return;
410412

411-
if (printSymbolizedStackTrace(StackTrace, depth, OS))
413+
if (printSymbolizedStackTrace(Argv0, StackTrace, depth, OS))
412414
return;
413415
#if HAVE_DLFCN_H && __GNUG__
414416
int width = 0;
@@ -471,7 +473,10 @@ void llvm::sys::DisableSystemDialogsOnCrash() {}
471473

472474
/// PrintStackTraceOnErrorSignal - When an error signal (such as SIGABRT or
473475
/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
474-
void llvm::sys::PrintStackTraceOnErrorSignal(bool DisableCrashReporting) {
476+
void llvm::sys::PrintStackTraceOnErrorSignal(StringRef Argv0,
477+
bool DisableCrashReporting) {
478+
::Argv0 = Argv0;
479+
475480
AddSignalHandler(PrintStackTraceSignalHandler, nullptr);
476481

477482
#if defined(__APPLE__) && defined(ENABLE_CRASH_OVERRIDES)

llvm/lib/Support/Windows/Signals.inc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL;
206206
static CRITICAL_SECTION CriticalSection;
207207
static bool CriticalSectionInitialized = false;
208208

209+
static StringRef Argv0;
210+
209211
enum {
210212
#if defined(_M_X64)
211213
NativeMachineType = IMAGE_FILE_MACHINE_AMD64
@@ -240,7 +242,7 @@ static bool printStackTraceWithLLVMSymbolizer(llvm::raw_ostream &OS,
240242
break;
241243
}
242244

243-
return printSymbolizedStackTrace(&StackTrace[0], Depth, OS);
245+
return printSymbolizedStackTrace(Argv0, &StackTrace[0], Depth, OS);
244246
}
245247

246248
namespace {
@@ -496,7 +498,10 @@ void sys::DisableSystemDialogsOnCrash() {
496498

497499
/// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or
498500
/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
499-
void sys::PrintStackTraceOnErrorSignal(bool DisableCrashReporting) {
501+
void sys::PrintStackTraceOnErrorSignal(StringRef Argv0,
502+
bool DisableCrashReporting) {
503+
::Argv0 = Argv0;
504+
500505
if (DisableCrashReporting || getenv("LLVM_DISABLE_CRASH_REPORT"))
501506
Process::PreventCoreFiles();
502507

llvm/tools/bugpoint/bugpoint.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ void initializePollyPasses(llvm::PassRegistry &Registry);
113113

114114
int main(int argc, char **argv) {
115115
#ifndef DEBUG_BUGPOINT
116-
llvm::sys::PrintStackTraceOnErrorSignal();
116+
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
117117
llvm::PrettyStackTraceProgram X(argc, argv);
118118
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
119119
#endif

llvm/tools/dsymutil/dsymutil.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ void llvm::dsymutil::exitDsymutil(int ExitStatus) {
237237
}
238238

239239
int main(int argc, char **argv) {
240-
llvm::sys::PrintStackTraceOnErrorSignal();
240+
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
241241
llvm::PrettyStackTraceProgram StackPrinter(argc, argv);
242242
llvm::llvm_shutdown_obj Shutdown;
243243
LinkOptions Options;

llvm/tools/llc/llc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ static void DiagnosticHandler(const DiagnosticInfo &DI, void *Context) {
202202
// main - Entry point for the llc compiler.
203203
//
204204
int main(int argc, char **argv) {
205-
sys::PrintStackTraceOnErrorSignal();
205+
sys::PrintStackTraceOnErrorSignal(argv[0]);
206206
PrettyStackTraceProgram X(argc, argv);
207207

208208
// Enable debug stream buffering.

llvm/tools/lli/lli.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ CodeGenOpt::Level getOptLevel() {
365365
// main Driver function
366366
//
367367
int main(int argc, char **argv, char * const *envp) {
368-
sys::PrintStackTraceOnErrorSignal();
368+
sys::PrintStackTraceOnErrorSignal(argv[0]);
369369
PrettyStackTraceProgram X(argc, argv);
370370

371371
atexit(llvm_shutdown); // Call llvm_shutdown() on exit.

llvm/tools/llvm-ar/llvm-ar.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ static int ranlib_main() {
773773
int main(int argc, char **argv) {
774774
ToolName = argv[0];
775775
// Print a stack trace if we signal out.
776-
sys::PrintStackTraceOnErrorSignal();
776+
sys::PrintStackTraceOnErrorSignal(argv[0]);
777777
PrettyStackTraceProgram X(argc, argv);
778778
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
779779

llvm/tools/llvm-as/llvm-as.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ static void WriteOutputFile(const Module *M) {
8989

9090
int main(int argc, char **argv) {
9191
// Print a stack trace if we signal out.
92-
sys::PrintStackTraceOnErrorSignal();
92+
sys::PrintStackTraceOnErrorSignal(argv[0]);
9393
PrettyStackTraceProgram X(argc, argv);
9494
LLVMContext Context;
9595
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.

0 commit comments

Comments
 (0)