From 54023f85e712eb169f3a4d4b20d133451839bd9a Mon Sep 17 00:00:00 2001 From: Hamish Knight Date: Thu, 3 Apr 2025 14:21:38 +0100 Subject: [PATCH 1/2] [Basic] Introduce `abortWithPrettyStackTraceMessage` Introduce a convenience for aborting while printing a given message to a frame of the pretty stack trace. Use this in the existing places where we're currently doing this. --- include/swift/Basic/PrettyStackTrace.h | 11 ++++++++ lib/AST/ASTScopePrinting.cpp | 15 +++++------ lib/Basic/PrettyStackTrace.cpp | 16 +++++++++++ lib/Serialization/ModuleFileSharedCore.cpp | 31 ++++++++++------------ lib/Serialization/Serialization.cpp | 7 +++-- 5 files changed, 50 insertions(+), 30 deletions(-) diff --git a/include/swift/Basic/PrettyStackTrace.h b/include/swift/Basic/PrettyStackTrace.h index a105d6a23b0ff..90bc97a5fd71e 100644 --- a/include/swift/Basic/PrettyStackTrace.h +++ b/include/swift/Basic/PrettyStackTrace.h @@ -50,6 +50,17 @@ class PrettyStackTraceSwiftVersion : public llvm::PrettyStackTraceEntry { void print(llvm::raw_ostream &OS) const override; }; +/// Aborts the program, printing a given message to a PrettyStackTrace frame +/// before exiting. +[[noreturn]] +void abortWithPrettyStackTraceMessage( + llvm::function_ref message); + +/// Aborts the program, printing a given message to a PrettyStackTrace frame +/// before exiting. +[[noreturn]] +void abortWithPrettyStackTraceMessage(llvm::StringRef message); + } // end namespace swift #endif // SWIFT_BASIC_PRETTYSTACKTRACE_H diff --git a/lib/AST/ASTScopePrinting.cpp b/lib/AST/ASTScopePrinting.cpp index 399fbca7d2cae..cedd542a2d59e 100644 --- a/lib/AST/ASTScopePrinting.cpp +++ b/lib/AST/ASTScopePrinting.cpp @@ -29,6 +29,7 @@ #include "swift/AST/Stmt.h" #include "swift/AST/TypeRepr.h" #include "swift/Basic/Assertions.h" +#include "swift/Basic/PrettyStackTrace.h" #include "swift/Basic/STLExtras.h" #include "llvm/Support/Compiler.h" #include @@ -71,15 +72,11 @@ void ASTScopeImpl::dumpOneScopeMapLocation( void ASTScopeImpl::abortWithVerificationError( llvm::function_ref messageFn) const { - llvm::SmallString<0> errorStr; - llvm::raw_svector_ostream out(errorStr); - - out << "ASTScopeImpl verification error in source file '" - << getSourceFile()->getFilename() << "':\n"; - messageFn(out); - - llvm::PrettyStackTraceString trace(errorStr.c_str()); - abort(); + abortWithPrettyStackTraceMessage([&](auto &out) { + out << "ASTScopeImpl verification error in source file '" + << getSourceFile()->getFilename() << "':\n"; + messageFn(out); + }); } #pragma mark printing diff --git a/lib/Basic/PrettyStackTrace.cpp b/lib/Basic/PrettyStackTrace.cpp index 9ea117b67a23e..afcbd1a5196df 100644 --- a/lib/Basic/PrettyStackTrace.cpp +++ b/lib/Basic/PrettyStackTrace.cpp @@ -18,6 +18,7 @@ #include "swift/Basic/PrettyStackTrace.h" #include "swift/Basic/QuotedString.h" #include "swift/Basic/Version.h" +#include "llvm/ADT/SmallString.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" @@ -38,3 +39,18 @@ void PrettyStackTraceFileContents::print(llvm::raw_ostream &out) const { void PrettyStackTraceSwiftVersion::print(llvm::raw_ostream &out) const { out << version::getSwiftFullVersion() << '\n'; } + +void swift::abortWithPrettyStackTraceMessage( + llvm::function_ref message) { + llvm::SmallString<0> errorStr; + llvm::raw_svector_ostream out(errorStr); + message(out); + llvm::PrettyStackTraceString trace(errorStr.c_str()); + abort(); +} + +void swift::abortWithPrettyStackTraceMessage(StringRef message) { + auto messageStr = message.str(); + llvm::PrettyStackTraceString trace(messageStr.c_str()); + abort(); +} diff --git a/lib/Serialization/ModuleFileSharedCore.cpp b/lib/Serialization/ModuleFileSharedCore.cpp index e79aa78e20455..7fc4bc287fcab 100644 --- a/lib/Serialization/ModuleFileSharedCore.cpp +++ b/lib/Serialization/ModuleFileSharedCore.cpp @@ -19,6 +19,7 @@ #include "swift/AST/Module.h" #include "swift/Basic/Assertions.h" #include "swift/Basic/LangOptions.h" +#include "swift/Basic/PrettyStackTrace.h" #include "swift/Parse/ParseVersion.h" #include "swift/Serialization/SerializedModuleLoader.h" #include "swift/Strings.h" @@ -697,23 +698,19 @@ std::string ModuleFileSharedCore::Dependency::getPrettyPrintedPath() const { } void ModuleFileSharedCore::fatal(llvm::Error error) const { - llvm::SmallString<0> errorStr; - llvm::raw_svector_ostream out(errorStr); - - out << "*** DESERIALIZATION FAILURE ***\n"; - out << "*** If any module named here was modified in the SDK, please delete the ***\n"; - out << "*** new swiftmodule files from the SDK and keep only swiftinterfaces. ***\n"; - outputDiagnosticInfo(out); - out << "\n"; - if (error) { - handleAllErrors(std::move(error), [&](const llvm::ErrorInfoBase &ei) { - ei.log(out); - out << "\n"; - }); - } - - llvm::PrettyStackTraceString trace(errorStr.c_str()); - abort(); + abortWithPrettyStackTraceMessage([&](auto &out) { + out << "*** DESERIALIZATION FAILURE ***\n"; + out << "*** If any module named here was modified in the SDK, please delete the ***\n"; + out << "*** new swiftmodule files from the SDK and keep only swiftinterfaces. ***\n"; + outputDiagnosticInfo(out); + out << "\n"; + if (error) { + handleAllErrors(std::move(error), [&](const llvm::ErrorInfoBase &ei) { + ei.log(out); + out << "\n"; + }); + } + }); } void ModuleFileSharedCore::outputDiagnosticInfo(llvm::raw_ostream &os) const { diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 5fcd564217888..3d318dee5168d 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -46,6 +46,7 @@ #include "swift/Basic/FileSystem.h" #include "swift/Basic/LLVMExtras.h" #include "swift/Basic/PathRemapper.h" +#include "swift/Basic/PrettyStackTrace.h" #include "swift/Basic/STLExtras.h" #include "swift/Basic/Version.h" #include "swift/ClangImporter/ClangImporter.h" @@ -5314,8 +5315,7 @@ void Serializer::writeASTBlockEntity(const Decl *D) { SWIFT_DEFER { // This is important enough to leave on in Release builds. if (initialOffset == Out.GetCurrentBitNo()) { - llvm::PrettyStackTraceString message("failed to serialize anything"); - abort(); + abortWithPrettyStackTraceMessage("failed to serialize anything"); } }; @@ -6141,8 +6141,7 @@ void Serializer::writeASTBlockEntity(Type ty) { SWIFT_DEFER { // This is important enough to leave on in Release builds. if (initialOffset == Out.GetCurrentBitNo()) { - llvm::PrettyStackTraceString message("failed to serialize anything"); - abort(); + abortWithPrettyStackTraceMessage("failed to serialize anything"); } }; From abf8a81a186199a1bd8bf6a5249e25fa4dcb8869 Mon Sep 17 00:00:00 2001 From: Hamish Knight Date: Thu, 3 Apr 2025 14:21:38 +0100 Subject: [PATCH 2/2] [Mangler] Use `abortWithPrettyStackTraceMessage` for verification errors Make sure we include the verification error in the crash log. --- lib/Basic/Mangler.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/Basic/Mangler.cpp b/lib/Basic/Mangler.cpp index 35bad0b1ad60d..8d6f410b58400 100644 --- a/lib/Basic/Mangler.cpp +++ b/lib/Basic/Mangler.cpp @@ -12,6 +12,7 @@ #include "swift/Basic/Mangler.h" #include "swift/Basic/Assertions.h" +#include "swift/Basic/PrettyStackTrace.h" #include "swift/Demangling/Demangler.h" #include "swift/Demangling/ManglingMacros.h" #include "swift/Demangling/Punycode.h" @@ -201,22 +202,25 @@ void Mangler::verify(StringRef nameStr, ManglingFlavor Flavor) { Demangler Dem; NodePointer Root = Dem.demangleSymbol(nameStr); if (!Root || treeContains(Root, Node::Kind::Suffix)) { - llvm::errs() << "Can't demangle: " << nameStr << '\n'; - abort(); + abortWithPrettyStackTraceMessage([&](auto &out) { + out << "Can't demangle: " << nameStr; + }); } auto mangling = mangleNode(Root, Flavor); if (!mangling.isSuccess()) { - llvm::errs() << "Can't remangle: " << nameStr << '\n'; - abort(); + abortWithPrettyStackTraceMessage([&](auto &out) { + out << "Can't remangle: " << nameStr; + }); } std::string Remangled = mangling.result(); if (Remangled == nameStr) return; - llvm::errs() << "Remangling failed:\n" - "original = " << nameStr << "\n" - "remangled = " << Remangled << "\n"; - abort(); + abortWithPrettyStackTraceMessage([&](auto &out) { + out << "Remangling failed:\n"; + out << "original = " << nameStr << "\n"; + out << "remangled = " << Remangled; + }); } void Mangler::appendIdentifier(StringRef ident, bool allowRawIdentifiers) {