diff --git a/llvm/include/llvm/Support/Signals.h b/llvm/include/llvm/Support/Signals.h --- a/llvm/include/llvm/Support/Signals.h +++ b/llvm/include/llvm/Support/Signals.h @@ -50,7 +50,9 @@ void DisableSystemDialogsOnCrash(); /// Print the stack trace using the given \c raw_ostream object. - void PrintStackTrace(raw_ostream &OS); + /// \param Depth refers to the number of stackframes to print. If not + /// specified, the entire frame is printed. + void PrintStackTrace(raw_ostream &OS, int Depth = 0); // Run all registered signal handlers. void RunSignalHandlers(); diff --git a/llvm/lib/Support/Unix/Signals.inc b/llvm/lib/Support/Unix/Signals.inc --- a/llvm/lib/Support/Unix/Signals.inc +++ b/llvm/lib/Support/Unix/Signals.inc @@ -553,7 +553,7 @@ // // On glibc systems we have the 'backtrace' function, which works nicely, but // doesn't demangle symbols. -void llvm::sys::PrintStackTrace(raw_ostream &OS) { +void llvm::sys::PrintStackTrace(raw_ostream &OS, int Depth) { #if ENABLE_BACKTRACES static void *StackTrace[256]; int depth = 0; @@ -570,8 +570,11 @@ #endif if (!depth) return; - - if (printSymbolizedStackTrace(Argv0, StackTrace, depth, OS)) + // If "Depth" is not provided by the caller, use the return value of + // backtrace() for printing a symbolized stack trace. + if (!Depth) + Depth = depth; + if (printSymbolizedStackTrace(Argv0, StackTrace, Depth, OS)) return; #if HAVE_DLFCN_H && HAVE_DLADDR int width = 0; @@ -614,7 +617,7 @@ OS << '\n'; } #elif defined(HAVE_BACKTRACE) - backtrace_symbols_fd(StackTrace, depth, STDERR_FILENO); + backtrace_symbols_fd(StackTrace, Depth, STDERR_FILENO); #endif #endif } diff --git a/llvm/lib/Support/Windows/Signals.inc b/llvm/lib/Support/Windows/Signals.inc --- a/llvm/lib/Support/Windows/Signals.inc +++ b/llvm/lib/Support/Windows/Signals.inc @@ -552,7 +552,8 @@ StackFrame, C); } -void llvm::sys::PrintStackTrace(raw_ostream &OS) { +void llvm::sys::PrintStackTrace(raw_ostream &OS, int Depth) { + // FIXME: Handle "Depth" parameter to print stack trace upto specified Depth LocalPrintStackTrace(OS, nullptr); } diff --git a/llvm/unittests/Support/CrashRecoveryTest.cpp b/llvm/unittests/Support/CrashRecoveryTest.cpp --- a/llvm/unittests/Support/CrashRecoveryTest.cpp +++ b/llvm/unittests/Support/CrashRecoveryTest.cpp @@ -6,10 +6,13 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Host.h" #include "llvm/Support/Signals.h" +#include "llvm/Support/raw_ostream.h" #include "gtest/gtest.h" #ifdef _WIN32 @@ -90,6 +93,17 @@ llvm::CrashRecoveryContext::Disable(); } +TEST(CrashRecoveryTest, LimitedStackTrace) { + std::string Res; + llvm::raw_string_ostream RawStream(Res); + PrintStackTrace(RawStream, 1); + std::string Str = RawStream.str(); + // FIXME: Handle "Depth" parameter in PrintStackTrace() function + // to print stack trace upto a specified Depth. + if (!Triple(sys::getProcessTriple()).isOSWindows()) + EXPECT_EQ(std::string::npos, Str.find("#1")); +} + #ifdef _WIN32 static void raiseIt() { RaiseException(123, EXCEPTION_NONCONTINUABLE, 0, NULL);