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 @@ -17,6 +17,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Triple.h" #include "gtest/gtest.h" +#include #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN @@ -114,6 +115,31 @@ EXPECT_EQ(std::string::npos, Str.find("#1")); } +#if defined(HAVE_BACKTRACE) && ENABLE_BACKTRACES && HAVE_LINK_H && \ + (defined(__linux__) || defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || defined(__NetBSD__)) +TEST(CrashRecoveryTest, SymbolizedStackTrace) { + std::string Res; + llvm::raw_string_ostream RawStream(Res); + PrintStackTrace(RawStream); + int ExpectedLine = __LINE__ - 1; // The line that calls PrintStackTrace. + std::string Str = RawStream.str(); + // Symbolized trace lines have "file:line:column", others "(file+offset)". + std::string ExpectedFile = __FILE__ ":"; // Match this file and the colon. + size_t ActualLineStartPos = Str.find(ExpectedFile) + ExpectedFile.length(); + ASSERT_NE(std::string::npos, ActualLineStartPos); + int ActualLine; + auto LineResult = std::from_chars(Str.data() + ActualLineStartPos, + Str.data() + Str.size(), ActualLine); + ASSERT_EQ(LineResult.ec, std::errc()); + // Check that the stack trace contains the correct line for this source file. + // At the time this test was added x86_64 Linux was printing the line after + // the PrintStackTrace call while AArch64 Linux was printing the expected line + // so for now we do a fuzzy match. + EXPECT_NEAR(ExpectedLine, ActualLine, 1); +} +#endif + #ifdef _WIN32 static void raiseIt() { RaiseException(123, EXCEPTION_NONCONTINUABLE, 0, NULL);