Move the internal PrintStackTrace function that is used for llvm::sys::PrintStackTraceOnErrorSignal(),
into a new function llvm::sys::PrintStackTrace, so that it's available to clients for logging purposes. llvm-svn: 171989
This commit is contained in:
parent
c189a392ce
commit
eb9ae76864
|
@ -38,6 +38,9 @@ namespace sys {
|
||||||
/// @brief Print a stack trace if a fatal signal occurs.
|
/// @brief Print a stack trace if a fatal signal occurs.
|
||||||
void PrintStackTraceOnErrorSignal();
|
void PrintStackTraceOnErrorSignal();
|
||||||
|
|
||||||
|
/// \brief Print the stack trace using the given \c FILE object.
|
||||||
|
void PrintStackTrace(FILE *);
|
||||||
|
|
||||||
/// AddSignalHandler - Add a function to be called when an abort/kill signal
|
/// AddSignalHandler - Add a function to be called when an abort/kill signal
|
||||||
/// is delivered to the process. The handler can have a cookie passed to it
|
/// is delivered to the process. The handler can have a cookie passed to it
|
||||||
/// to identify what instance of the handler it is.
|
/// to identify what instance of the handler it is.
|
||||||
|
|
|
@ -254,7 +254,7 @@ void llvm::sys::AddSignalHandler(void (*FnPtr)(void *), void *Cookie) {
|
||||||
//
|
//
|
||||||
// On glibc systems we have the 'backtrace' function, which works nicely, but
|
// On glibc systems we have the 'backtrace' function, which works nicely, but
|
||||||
// doesn't demangle symbols.
|
// doesn't demangle symbols.
|
||||||
static void PrintStackTrace(void *) {
|
void llvm::sys::PrintStackTrace(FILE *FD) {
|
||||||
#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
|
#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
|
||||||
static void* StackTrace[256];
|
static void* StackTrace[256];
|
||||||
// Use backtrace() to output a backtrace on Linux systems with glibc.
|
// Use backtrace() to output a backtrace on Linux systems with glibc.
|
||||||
|
@ -278,26 +278,26 @@ static void PrintStackTrace(void *) {
|
||||||
Dl_info dlinfo;
|
Dl_info dlinfo;
|
||||||
dladdr(StackTrace[i], &dlinfo);
|
dladdr(StackTrace[i], &dlinfo);
|
||||||
|
|
||||||
fprintf(stderr, "%-2d", i);
|
fprintf(FD, "%-2d", i);
|
||||||
|
|
||||||
const char* name = strrchr(dlinfo.dli_fname, '/');
|
const char* name = strrchr(dlinfo.dli_fname, '/');
|
||||||
if (name == NULL) fprintf(stderr, " %-*s", width, dlinfo.dli_fname);
|
if (name == NULL) fprintf(FD, " %-*s", width, dlinfo.dli_fname);
|
||||||
else fprintf(stderr, " %-*s", width, name+1);
|
else fprintf(FD, " %-*s", width, name+1);
|
||||||
|
|
||||||
fprintf(stderr, " %#0*lx",
|
fprintf(FD, " %#0*lx",
|
||||||
(int)(sizeof(void*) * 2) + 2, (unsigned long)StackTrace[i]);
|
(int)(sizeof(void*) * 2) + 2, (unsigned long)StackTrace[i]);
|
||||||
|
|
||||||
if (dlinfo.dli_sname != NULL) {
|
if (dlinfo.dli_sname != NULL) {
|
||||||
int res;
|
int res;
|
||||||
fputc(' ', stderr);
|
fputc(' ', FD);
|
||||||
char* d = abi::__cxa_demangle(dlinfo.dli_sname, NULL, NULL, &res);
|
char* d = abi::__cxa_demangle(dlinfo.dli_sname, NULL, NULL, &res);
|
||||||
if (d == NULL) fputs(dlinfo.dli_sname, stderr);
|
if (d == NULL) fputs(dlinfo.dli_sname, FD);
|
||||||
else fputs(d, stderr);
|
else fputs(d, FD);
|
||||||
free(d);
|
free(d);
|
||||||
|
|
||||||
fprintf(stderr, " + %tu",(char*)StackTrace[i]-(char*)dlinfo.dli_saddr);
|
fprintf(FD, " + %tu",(char*)StackTrace[i]-(char*)dlinfo.dli_saddr);
|
||||||
}
|
}
|
||||||
fputc('\n', stderr);
|
fputc('\n', FD);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO);
|
backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO);
|
||||||
|
@ -305,10 +305,14 @@ static void PrintStackTrace(void *) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void PrintStackTraceSignalHandler(void *) {
|
||||||
|
PrintStackTrace(stderr);
|
||||||
|
}
|
||||||
|
|
||||||
/// PrintStackTraceOnErrorSignal - When an error signal (such as SIGABRT or
|
/// PrintStackTraceOnErrorSignal - When an error signal (such as SIGABRT or
|
||||||
/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
|
/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
|
||||||
void llvm::sys::PrintStackTraceOnErrorSignal() {
|
void llvm::sys::PrintStackTraceOnErrorSignal() {
|
||||||
AddSignalHandler(PrintStackTrace, 0);
|
AddSignalHandler(PrintStackTraceSignalHandler, 0);
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
// Environment variable to disable any kind of crash dialog.
|
// Environment variable to disable any kind of crash dialog.
|
||||||
|
|
|
@ -295,6 +295,10 @@ void sys::PrintStackTraceOnErrorSignal() {
|
||||||
LeaveCriticalSection(&CriticalSection);
|
LeaveCriticalSection(&CriticalSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void llvm::sys::PrintStackTrace(FILE *) {
|
||||||
|
// FIXME: Implement.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void sys::SetInterruptFunction(void (*IF)()) {
|
void sys::SetInterruptFunction(void (*IF)()) {
|
||||||
RegisterHandler();
|
RegisterHandler();
|
||||||
|
|
Loading…
Reference in New Issue