Skip to content

Commit

Permalink
Move the internal PrintStackTrace function that is used for llvm::sys…
Browse files Browse the repository at this point in the history
…::PrintStackTraceOnErrorSignal(),

into a new function llvm::sys::PrintStackTrace, so that it's available to clients for logging purposes.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171989 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
akyrtzi committed Jan 9, 2013
1 parent 5581115 commit f48acd5
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 11 deletions.
3 changes: 3 additions & 0 deletions include/llvm/Support/Signals.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ namespace sys {
/// @brief Print a stack trace if a fatal signal occurs.
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
/// is delivered to the process. The handler can have a cookie passed to it
/// to identify what instance of the handler it is.
Expand Down
26 changes: 15 additions & 11 deletions lib/Support/Unix/Signals.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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
// doesn't demangle symbols.
static void PrintStackTrace(void *) {
void llvm::sys::PrintStackTrace(FILE *FD) {
#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
static void* StackTrace[256];
// Use backtrace() to output a backtrace on Linux systems with glibc.
Expand All @@ -278,37 +278,41 @@ static void PrintStackTrace(void *) {
Dl_info dlinfo;
dladdr(StackTrace[i], &dlinfo);

fprintf(stderr, "%-2d", i);
fprintf(FD, "%-2d", i);

const char* name = strrchr(dlinfo.dli_fname, '/');
if (name == NULL) fprintf(stderr, " %-*s", width, dlinfo.dli_fname);
else fprintf(stderr, " %-*s", width, name+1);
if (name == NULL) fprintf(FD, " %-*s", width, dlinfo.dli_fname);
else fprintf(FD, " %-*s", width, name+1);

fprintf(stderr, " %#0*lx",
fprintf(FD, " %#0*lx",
(int)(sizeof(void*) * 2) + 2, (unsigned long)StackTrace[i]);

if (dlinfo.dli_sname != NULL) {
int res;
fputc(' ', stderr);
fputc(' ', FD);
char* d = abi::__cxa_demangle(dlinfo.dli_sname, NULL, NULL, &res);
if (d == NULL) fputs(dlinfo.dli_sname, stderr);
else fputs(d, stderr);
if (d == NULL) fputs(dlinfo.dli_sname, FD);
else fputs(d, FD);
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
backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO);
#endif
#endif
}

static void PrintStackTraceSignalHandler(void *) {
PrintStackTrace(stderr);
}

/// 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() {
AddSignalHandler(PrintStackTrace, 0);
AddSignalHandler(PrintStackTraceSignalHandler, 0);

#if defined(__APPLE__)
// Environment variable to disable any kind of crash dialog.
Expand Down
4 changes: 4 additions & 0 deletions lib/Support/Windows/Signals.inc
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,10 @@ void sys::PrintStackTraceOnErrorSignal() {
LeaveCriticalSection(&CriticalSection);
}

void llvm::sys::PrintStackTrace(FILE *) {
// FIXME: Implement.
}


void sys::SetInterruptFunction(void (*IF)()) {
RegisterHandler();
Expand Down

0 comments on commit f48acd5

Please sign in to comment.