Index: llvm/trunk/include/llvm/Support/Signals.h =================================================================== --- llvm/trunk/include/llvm/Support/Signals.h +++ llvm/trunk/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: llvm/trunk/lib/Support/Unix/Signals.inc =================================================================== --- llvm/trunk/lib/Support/Unix/Signals.inc +++ llvm/trunk/lib/Support/Unix/Signals.inc @@ -14,6 +14,7 @@ #include "Unix.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Format.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FileUtilities.h" #include "llvm/Support/ManagedStatic.h" @@ -324,7 +325,8 @@ } #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. @@ -382,7 +384,7 @@ int frame_no = 0; for (int i = 0; i < Depth; i++) { if (!Modules[i]) { - fprintf(FD, "#%d %p\n", frame_no++, StackTrace[i]); + OS << format("#%d %p\n", frame_no++, StackTrace[i]); continue; } // Read pairs of lines (function name and file/line info) until we @@ -393,17 +395,17 @@ StringRef FunctionName = *CurLine++; if (FunctionName.empty()) break; - fprintf(FD, "#%d %p ", frame_no++, StackTrace[i]); + OS << format("#%d %p ", frame_no++, StackTrace[i]); if (!FunctionName.startswith("??")) - fprintf(FD, "%s ", FunctionName.str().c_str()); + OS << format("%s ", FunctionName.str().c_str()); if (CurLine == Lines.end()) return false; StringRef FileLineInfo = *CurLine++; if (!FileLineInfo.startswith("??")) - fprintf(FD, "%s", FileLineInfo.str().c_str()); + OS << format("%s", FileLineInfo.str().c_str()); else - fprintf(FD, "(%s+%p)", Modules[i], (void *)Offsets[i]); - fprintf(FD, "\n"); + OS << format("(%s+%p)", Modules[i], (void *)Offsets[i]); + OS << "\n"; } } return true; @@ -415,13 +417,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 +443,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", - (int)(sizeof(void*) * 2) + 2, (unsigned long)StackTrace[i]); + 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 +479,7 @@ } static void PrintStackTraceSignalHandler(void *) { - PrintStackTrace(stderr); + PrintStackTrace(llvm::errs()); } void llvm::sys::DisableSystemDialogsOnCrash() {} Index: llvm/trunk/lib/Support/Windows/Signals.inc =================================================================== --- llvm/trunk/lib/Support/Windows/Signals.inc +++ llvm/trunk/lib/Support/Windows/Signals.inc @@ -16,6 +16,9 @@ #include #include +#include "llvm/Support/Format.h" +#include "llvm/Support/raw_ostream.h" + // The Windows.h header must be after LLVM and standard headers. #include "WindowsSupport.h" @@ -172,7 +175,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; @@ -195,21 +198,22 @@ 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)", + 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)", + 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]), @@ -217,7 +221,7 @@ #endif // Verify the PC belongs to a module in this process. if (!SymGetModuleBase64(hProcess, PC)) { - fputs(" \n", File); + OS << " \n"; continue; } @@ -230,15 +234,16 @@ 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; @@ -246,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'; } } @@ -381,7 +386,7 @@ LeaveCriticalSection(&CriticalSection); } -void llvm::sys::PrintStackTrace(FILE *File) { +void llvm::sys::PrintStackTrace(raw_ostream &OS) { STACKFRAME64 StackFrame = {}; CONTEXT Context = {0}; @@ -398,7 +403,7 @@ StackFrame.AddrPC.Mode = AddrModeFlat; StackFrame.AddrStack.Mode = AddrModeFlat; StackFrame.AddrFrame.Mode = AddrModeFlat; - PrintStackTraceForThread(File, GetCurrentProcess(), GetCurrentThread(), + PrintStackTraceForThread(OS, GetCurrentProcess(), GetCurrentThread(), StackFrame, &Context); } @@ -473,7 +478,7 @@ HANDLE hProcess = GetCurrentProcess(); HANDLE hThread = GetCurrentThread(); - PrintStackTraceForThread(stderr, hProcess, hThread, StackFrame, + PrintStackTraceForThread(llvm::errs(), hProcess, hThread, StackFrame, ep->ContextRecord); _exit(ep->ExceptionRecord->ExceptionCode);