Index: include/llvm/Support/Signals.h =================================================================== --- include/llvm/Support/Signals.h +++ include/llvm/Support/Signals.h @@ -19,6 +19,8 @@ #include namespace llvm { + class raw_ostream; + namespace sys { /// This function runs all the registered interrupt handlers, including the @@ -42,8 +44,8 @@ /// Disable all system dialog boxes that appear when the process crashes. void DisableSystemDialogsOnCrash(); - /// \brief Print the stack trace using the given \c FILE object. - void PrintStackTrace(FILE *); + /// \brief Print the stack trace using the given \c raw_ostream object. + void PrintStackTrace(raw_ostream &OS); /// 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 Index: lib/Support/Unix/Signals.inc =================================================================== --- lib/Support/Unix/Signals.inc +++ lib/Support/Unix/Signals.inc @@ -324,7 +324,7 @@ } #endif -static bool printSymbolizedStackTrace(void **StackTrace, int Depth, FILE *FD) { +static bool printSymbolizedStackTrace(void **StackTrace, int Depth, llvm::raw_ostream &OS) { // FIXME: Subtract necessary number from StackTrace entries to turn return addresses // into actual instruction addresses. // Use llvm-symbolizer tool to symbolize the stack traces. @@ -415,13 +415,13 @@ // // On glibc systems we have the 'backtrace' function, which works nicely, but // doesn't demangle symbols. -void llvm::sys::PrintStackTrace(FILE *FD) { +void llvm::sys::PrintStackTrace(raw_ostream &OS) { #if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES) static void* StackTrace[256]; // Use backtrace() to output a backtrace on Linux systems with glibc. int depth = backtrace(StackTrace, static_cast(array_lengthof(StackTrace))); - if (printSymbolizedStackTrace(StackTrace, depth, FD)) + if (printSymbolizedStackTrace(StackTrace, depth, OS)) return; #if HAVE_DLFCN_H && __GNUG__ int width = 0; @@ -441,34 +441,34 @@ Dl_info dlinfo; dladdr(StackTrace[i], &dlinfo); - fprintf(FD, "%-2d", i); + OS << format("%-2d", i); const char* name = strrchr(dlinfo.dli_fname, '/'); - if (!name) fprintf(FD, " %-*s", width, dlinfo.dli_fname); - else fprintf(FD, " %-*s", width, name+1); + if (!name) OS << format(" %-*s", width, dlinfo.dli_fname); + else OS << format(" %-*s", width, name+1); - fprintf(FD, " %#0*lx", + OS << format(" %#0*lx", (int)(sizeof(void*) * 2) + 2, (unsigned long)StackTrace[i]); if (dlinfo.dli_sname != nullptr) { - fputc(' ', FD); + OS << ' '; # if HAVE_CXXABI_H int res; char* d = abi::__cxa_demangle(dlinfo.dli_sname, nullptr, nullptr, &res); # else char* d = NULL; # endif - if (!d) fputs(dlinfo.dli_sname, FD); - else fputs(d, FD); + if (!d) OS << dlinfo.dli_sname; + else OS << d; free(d); // FIXME: When we move to C++11, use %t length modifier. It's not in // C++03 and causes gcc to issue warnings. Losing the upper 32 bits of // the stack offset for a stack dump isn't likely to cause any problems. - fprintf(FD, " + %u",(unsigned)((char*)StackTrace[i]- - (char*)dlinfo.dli_saddr)); + OS << format(" + %u",(unsigned)((char*)StackTrace[i]- + (char*)dlinfo.dli_saddr)); } - fputc('\n', FD); + OS << '\n'; } #else backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO); @@ -477,7 +477,7 @@ } static void PrintStackTraceSignalHandler(void *) { - PrintStackTrace(stderr); + PrintStackTrace(errs()); } void llvm::sys::DisableSystemDialogsOnCrash() {} Index: lib/Support/Windows/Signals.inc =================================================================== --- lib/Support/Windows/Signals.inc +++ lib/Support/Windows/Signals.inc @@ -11,6 +11,9 @@ // //===----------------------------------------------------------------------===// #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/raw_os_ostream.h" #include #include #include @@ -173,7 +176,7 @@ // globals which this critical section addresses. static CRITICAL_SECTION CriticalSection; -static void PrintStackTraceForThread(FILE *File, HANDLE hProcess, +static void PrintStackTraceForThread(llvm::raw_ostream &OS, HANDLE hProcess, HANDLE hThread, STACKFRAME64 &StackFrame, CONTEXT *Context) { DWORD machineType; @@ -196,29 +199,30 @@ if (StackFrame.AddrFrame.Offset == 0) break; + using namespace llvm; // Print the PC in hexadecimal. DWORD64 PC = StackFrame.AddrPC.Offset; #if defined(_M_X64) - fprintf(File, "0x%016llX", PC); + OS << format("0x%016llX", PC); #elif defined(_M_IX86) - fprintf(File, "0x%08lX", static_cast(PC)); + OS << format("0x%08lX", static_cast(PC)); #endif // Print the parameters. Assume there are four. #if defined(_M_X64) - fprintf(File, " (0x%016llX 0x%016llX 0x%016llX 0x%016llX)", - StackFrame.Params[0], StackFrame.Params[1], StackFrame.Params[2], - StackFrame.Params[3]); + OS << format(" (0x%016llX 0x%016llX 0x%016llX 0x%016llX)", + StackFrame.Params[0], StackFrame.Params[1], + StackFrame.Params[2], StackFrame.Params[3]); #elif defined(_M_IX86) - fprintf(File, " (0x%08lX 0x%08lX 0x%08lX 0x%08lX)", - static_cast(StackFrame.Params[0]), - static_cast(StackFrame.Params[1]), - static_cast(StackFrame.Params[2]), - static_cast(StackFrame.Params[3])); + OS << format(" (0x%08lX 0x%08lX 0x%08lX 0x%08lX)", + static_cast(StackFrame.Params[0]), + static_cast(StackFrame.Params[1]), + static_cast(StackFrame.Params[2]), + static_cast(StackFrame.Params[3])); #endif // Verify the PC belongs to a module in this process. if (!SymGetModuleBase64(hProcess, PC)) { - fputs(" \n", File); + OS << " \n"; continue; } @@ -231,15 +235,15 @@ DWORD64 dwDisp; if (!SymGetSymFromAddr64(hProcess, PC, &dwDisp, symbol)) { - fputc('\n', File); + OS << '\n'; continue; } buffer[511] = 0; if (dwDisp > 0) - fprintf(File, ", %s() + 0x%llX bytes(s)", symbol->Name, dwDisp); + OS << format(", %s() + 0x%llX bytes(s)", (const char *)symbol->Name, dwDisp); else - fprintf(File, ", %s", symbol->Name); + OS << format(", %s", (const char *)symbol->Name); // Print the source file and line number information. IMAGEHLP_LINE64 line; @@ -247,12 +251,12 @@ memset(&line, 0, sizeof(line)); line.SizeOfStruct = sizeof(line); if (SymGetLineFromAddr64(hProcess, PC, &dwLineDisp, &line)) { - fprintf(File, ", %s, line %lu", line.FileName, line.LineNumber); + OS << format(", %s, line %lu", line.FileName, line.LineNumber); if (dwLineDisp > 0) - fprintf(File, " + 0x%lX byte(s)", dwLineDisp); + OS << format(" + 0x%lX byte(s)", dwLineDisp); } - fputc('\n', File); + OS << '\n'; } } @@ -382,8 +386,7 @@ LeaveCriticalSection(&CriticalSection); } -void llvm::sys::PrintStackTrace(FILE *File) { - +void llvm::sys::PrintStackTrace(raw_ostream &OS) { STACKFRAME64 StackFrame = {0}; CONTEXT Context = {0}; ::RtlCaptureContext(&Context); @@ -399,11 +402,10 @@ StackFrame.AddrPC.Mode = AddrModeFlat; StackFrame.AddrStack.Mode = AddrModeFlat; StackFrame.AddrFrame.Mode = AddrModeFlat; - PrintStackTraceForThread(File, GetCurrentProcess(), GetCurrentThread(), + PrintStackTraceForThread(OS, GetCurrentProcess(), GetCurrentThread(), StackFrame, &Context); } - void sys::SetInterruptFunction(void (*IF)()) { RegisterHandler(); InterruptFunction = IF; @@ -474,7 +476,7 @@ HANDLE hProcess = GetCurrentProcess(); HANDLE hThread = GetCurrentThread(); - PrintStackTraceForThread(stderr, hProcess, hThread, StackFrame, + PrintStackTraceForThread(llvm::errs(), hProcess, hThread, StackFrame, ep->ContextRecord); _exit(ep->ExceptionRecord->ExceptionCode);