Skip to content

Commit a68ce7b

Browse files
authored
Merge pull request #37743 from bnbarham/prefer-pretty-stack-trace
Add all deserialization fatal output to the pretty stack trace
2 parents 8e656ee + 599ba8b commit a68ce7b

File tree

12 files changed

+123
-125
lines changed

12 files changed

+123
-125
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -792,14 +792,6 @@ ERROR(serialization_fatal,Fatal,
792792
"fatal error encountered while reading from module '%0'; "
793793
SWIFT_BUG_REPORT_MESSAGE,
794794
(StringRef))
795-
NOTE(serialization_misc_version,none,
796-
"module '%0' full misc version is '%1'"
797-
"%select{ (built while allowing compiler errors)|}2",
798-
(StringRef, StringRef, bool))
799-
NOTE(serialization_compatibility_version_mismatch,none,
800-
"compiling as Swift %0, with '%1' built as Swift %2 "
801-
"(this is supported but may expose additional compiler issues)",
802-
(StringRef, StringRef, StringRef))
803795

804796
ERROR(serialization_invalid_decl,Fatal,
805797
"deserialized invalid declaration %0 (%1) in module '%2'",

lib/FrontendTool/FrontendTool.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include "swift/Basic/SourceManager.h"
4949
#include "swift/Basic/Statistic.h"
5050
#include "swift/Basic/UUID.h"
51+
#include "swift/Basic/Version.h"
5152
#include "swift/Option/Options.h"
5253
#include "swift/Frontend/Frontend.h"
5354
#include "swift/Frontend/AccumulatingDiagnosticConsumer.h"
@@ -1953,6 +1954,23 @@ static void printTargetInfo(const CompilerInvocation &invocation,
19531954
out << "}\n";
19541955
}
19551956

1957+
/// A PrettyStackTraceEntry to print frontend information useful for debugging.
1958+
class PrettyStackTraceFrontend : public llvm::PrettyStackTraceEntry {
1959+
const LangOptions &LangOpts;
1960+
1961+
public:
1962+
PrettyStackTraceFrontend(const LangOptions &langOpts)
1963+
: LangOpts(langOpts) {}
1964+
1965+
void print(llvm::raw_ostream &os) const override {
1966+
auto effective = LangOpts.EffectiveLanguageVersion;
1967+
if (effective != version::Version::getCurrentLanguageVersion()) {
1968+
os << "Compiling with effective version " << effective;
1969+
}
1970+
os << "\n";
1971+
};
1972+
};
1973+
19561974
int swift::performFrontend(ArrayRef<const char *> Args,
19571975
const char *Argv0, void *MainAddr,
19581976
FrontendObserver *observer) {
@@ -2046,10 +2064,7 @@ int swift::performFrontend(ArrayRef<const char *> Args,
20462064
return finishDiagProcessing(1, /*verifierEnabled*/ false);
20472065
}
20482066

2049-
Optional<llvm::PrettyStackTraceString> allowErrorsStackTrace;
2050-
if (Invocation.getFrontendOptions().AllowModuleWithCompilerErrors)
2051-
allowErrorsStackTrace.emplace("While allowing modules with compiler errors "
2052-
"enabled");
2067+
PrettyStackTraceFrontend frontendTrace(Invocation.getLangOptions());
20532068

20542069
// Make an array of PrettyStackTrace objects to dump the configuration files
20552070
// we used to parse the arguments. These are RAII objects, so they and the

lib/Serialization/Deserialization.cpp

Lines changed: 10 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ using namespace swift;
5757
using namespace swift::serialization;
5858
using llvm::Expected;
5959

60-
StringRef swift::getNameOfModule(const ModuleFile *MF) {
61-
return MF->getName();
62-
}
63-
6460
namespace {
6561
struct DeclAndOffset {
6662
const Decl *D;
@@ -111,7 +107,7 @@ namespace {
111107
os << DeclAndOffset{DeclOrOffset.get(), offset};
112108
}
113109
}
114-
os << " in '" << getNameOfModule(MF) << "'\n";
110+
os << " in '" << MF->getName() << "'\n";
115111
}
116112
};
117113

@@ -166,33 +162,15 @@ static void skipRecord(llvm::BitstreamCursor &cursor, unsigned recordKind) {
166162
(void)kind;
167163
}
168164

169-
void ModuleFile::fatal(llvm::Error error) {
170-
if (FileContext) {
171-
getContext().Diags.diagnose(SourceLoc(), diag::serialization_fatal, Core->Name);
172-
getContext().Diags.diagnose(
173-
SourceLoc(), diag::serialization_misc_version, Core->Name,
174-
Core->MiscVersion, allowCompilerErrors());
175-
176-
if (!Core->CompatibilityVersion.empty()) {
177-
if (getContext().LangOpts.EffectiveLanguageVersion
178-
!= Core->CompatibilityVersion) {
179-
SmallString<16> effectiveVersionBuffer, compatVersionBuffer;
180-
{
181-
llvm::raw_svector_ostream out(effectiveVersionBuffer);
182-
out << getContext().LangOpts.EffectiveLanguageVersion;
183-
}
184-
{
185-
llvm::raw_svector_ostream out(compatVersionBuffer);
186-
out << Core->CompatibilityVersion;
187-
}
188-
getContext().Diags.diagnose(
189-
SourceLoc(), diag::serialization_compatibility_version_mismatch,
190-
effectiveVersionBuffer, Core->Name, compatVersionBuffer);
191-
}
192-
}
193-
}
165+
void ModuleFile::fatal(llvm::Error error) const {
166+
if (FileContext)
167+
getContext().Diags.diagnose(SourceLoc(), diag::serialization_fatal,
168+
Core->Name);
169+
Core->fatal(std::move(error));
170+
}
194171

195-
ModuleFileSharedCore::fatal(std::move(error));
172+
void ModuleFile::outputDiagnosticInfo(llvm::raw_ostream &os) const {
173+
Core->outputDiagnosticInfo(os);
196174
}
197175

198176
static Optional<swift::AccessorKind>
@@ -6294,7 +6272,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
62946272
uint64_t contextData) {
62956273
using namespace decls_block;
62966274

6297-
PrettyStackTraceModuleFile traceModule("While reading from", *this);
6275+
PrettyStackTraceModuleFile traceModule(*this);
62986276
PrettyStackTraceConformance trace("finishing conformance for",
62996277
conformance);
63006278
++NumNormalProtocolConformancesCompleted;
@@ -6710,9 +6688,3 @@ Optional<ForeignAsyncConvention> ModuleFile::maybeReadForeignAsyncConvention() {
67106688
completionHandlerErrorFlagParamIndex,
67116689
errorFlagPolarity);
67126690
}
6713-
6714-
void serialization::PrettyStackTraceModuleFile::outputModuleBuildInfo(
6715-
raw_ostream &os) const {
6716-
if (MF.compiledAllowingCompilerErrors())
6717-
os << " (built while allowing compiler errors)";
6718-
}

lib/Serialization/DeserializationErrors.h

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,15 @@
1313
#ifndef SWIFT_SERIALIZATION_DESERIALIZATIONERRORS_H
1414
#define SWIFT_SERIALIZATION_DESERIALIZATIONERRORS_H
1515

16+
#include "ModuleFile.h"
17+
#include "ModuleFileSharedCore.h"
1618
#include "ModuleFormat.h"
1719
#include "swift/AST/Identifier.h"
1820
#include "swift/AST/Module.h"
1921
#include "llvm/Support/Error.h"
2022
#include "llvm/Support/PrettyStackTrace.h"
2123

2224
namespace swift {
23-
class ModuleFile;
24-
class ModuleFileSharedCore;
25-
26-
StringRef getNameOfModule(const ModuleFile *);
27-
StringRef getNameOfModule(const ModuleFileSharedCore *);
28-
2925
namespace serialization {
3026

3127
class XRefTracePath {
@@ -470,12 +466,10 @@ class PrettyStackTraceModuleFile : public llvm::PrettyStackTraceEntry {
470466
: PrettyStackTraceModuleFile("While reading from", module) {}
471467

472468
void print(raw_ostream &os) const override {
473-
os << Action << " \'" << getNameOfModule(&MF) << "'";
474-
outputModuleBuildInfo(os);
469+
os << Action << " ";
470+
MF.outputDiagnosticInfo(os);
475471
os << "\n";
476472
}
477-
478-
void outputModuleBuildInfo(raw_ostream &os) const;
479473
};
480474

481475
class PrettyStackTraceModuleFileCore : public llvm::PrettyStackTraceEntry {
@@ -485,7 +479,9 @@ class PrettyStackTraceModuleFileCore : public llvm::PrettyStackTraceEntry {
485479
: MF(module) {}
486480

487481
void print(raw_ostream &os) const override {
488-
os << "While reading from \'" << getNameOfModule(&MF) << "'\n";
482+
os << "While reading from ";
483+
MF.outputDiagnosticInfo(os);
484+
os << "\n";
489485
}
490486
};
491487

lib/Serialization/ModuleFile.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,6 @@ class ModuleFile
7575
llvm::BitstreamCursor SILIndexCursor;
7676
llvm::BitstreamCursor DeclMemberTablesCursor;
7777

78-
friend StringRef getNameOfModule(const ModuleFile *);
79-
8078
public:
8179
static std::unique_ptr<llvm::MemoryBuffer> getModuleName(ASTContext &Ctx,
8280
StringRef modulePath,
@@ -333,24 +331,27 @@ class ModuleFile
333331
return issue;
334332
}
335333

336-
/// Emits one last diagnostic, logs the error, and then aborts for the stack
337-
/// trace.
338-
LLVM_ATTRIBUTE_NORETURN void fatal(llvm::Error error);
339-
void fatalIfNotSuccess(llvm::Error error) {
334+
/// Emits one last diagnostic, adds the current module details and errors to
335+
/// the pretty stack trace, and then aborts.
336+
LLVM_ATTRIBUTE_NORETURN void fatal(llvm::Error error) const;
337+
void fatalIfNotSuccess(llvm::Error error) const {
340338
if (error)
341339
fatal(std::move(error));
342340
}
343-
template <typename T> T fatalIfUnexpected(llvm::Expected<T> expected) {
341+
template <typename T> T fatalIfUnexpected(llvm::Expected<T> expected) const {
344342
if (expected)
345343
return std::move(expected.get());
346344
fatal(expected.takeError());
347345
}
348346

349-
LLVM_ATTRIBUTE_NORETURN void fatal() {
347+
LLVM_ATTRIBUTE_NORETURN void fatal() const {
350348
fatal(llvm::make_error<llvm::StringError>(
351349
"(see \"While...\" info below)", llvm::inconvertibleErrorCode()));
352350
}
353351

352+
/// Outputs information useful for diagnostics to \p out
353+
void outputDiagnosticInfo(llvm::raw_ostream &os) const;
354+
354355
ASTContext &getContext() const {
355356
assert(FileContext && "no associated context yet");
356357
return FileContext->getParentModule()->getASTContext();

lib/Serialization/ModuleFileSharedCore.cpp

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,17 @@
1414
#include "ModuleFileCoreTableInfo.h"
1515
#include "BCReadingExtras.h"
1616
#include "DeserializationErrors.h"
17+
#include "swift/Basic/LangOptions.h"
1718
#include "swift/Strings.h"
1819
#include "llvm/Support/MemoryBuffer.h"
1920
#include "llvm/Support/OnDiskHashTable.h"
21+
#include "llvm/Support/PrettyStackTrace.h"
2022

2123
using namespace swift;
2224
using namespace swift::serialization;
2325
using namespace llvm::support;
2426
using llvm::Expected;
2527

26-
StringRef swift::getNameOfModule(const ModuleFileSharedCore *MF) {
27-
return MF->getName();
28-
}
29-
3028
static bool checkModuleSignature(llvm::BitstreamCursor &cursor,
3129
ArrayRef<unsigned char> signature) {
3230
for (unsigned char byte : signature) {
@@ -472,13 +470,31 @@ std::string ModuleFileSharedCore::Dependency::getPrettyPrintedPath() const {
472470
return output;
473471
}
474472

475-
void ModuleFileSharedCore::fatal(llvm::Error error) {
476-
logAllUnhandledErrors(std::move(error), llvm::errs(),
477-
"\n*** DESERIALIZATION FAILURE (please include this "
478-
"section in any bug report) ***\n");
473+
void ModuleFileSharedCore::fatal(llvm::Error error) const {
474+
llvm::SmallString<0> errorStr;
475+
llvm::raw_svector_ostream out(errorStr);
476+
477+
out << "*** DESERIALIZATION FAILURE ***\n";
478+
outputDiagnosticInfo(out);
479+
out << "\n";
480+
if (error) {
481+
handleAllErrors(std::move(error), [&](const llvm::ErrorInfoBase &ei) {
482+
ei.log(out);
483+
out << "\n";
484+
});
485+
}
486+
487+
llvm::PrettyStackTraceString trace(errorStr.c_str());
479488
abort();
480489
}
481490

491+
void ModuleFileSharedCore::outputDiagnosticInfo(llvm::raw_ostream &os) const {
492+
os << "module '" << Name << "' with full misc version '" << MiscVersion
493+
<< "'";
494+
if (Bits.IsAllowModuleWithCompilerErrorsEnabled)
495+
os << " (built with -experimental-allow-module-with-compiler-errors)";
496+
}
497+
482498
ModuleFileSharedCore::~ModuleFileSharedCore() { }
483499

484500
std::unique_ptr<ModuleFileSharedCore::SerializedDeclTable>

lib/Serialization/ModuleFileSharedCore.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,12 +371,12 @@ class ModuleFileSharedCore {
371371

372372
/// Emits one last diagnostic, logs the error, and then aborts for the stack
373373
/// trace.
374-
LLVM_ATTRIBUTE_NORETURN static void fatal(llvm::Error error);
375-
void fatalIfNotSuccess(llvm::Error error) {
374+
LLVM_ATTRIBUTE_NORETURN void fatal(llvm::Error error) const;
375+
void fatalIfNotSuccess(llvm::Error error) const {
376376
if (error)
377377
fatal(std::move(error));
378378
}
379-
template <typename T> T fatalIfUnexpected(llvm::Expected<T> expected) {
379+
template <typename T> T fatalIfUnexpected(llvm::Expected<T> expected) const {
380380
if (expected)
381381
return std::move(expected.get());
382382
fatal(expected.takeError());
@@ -508,6 +508,9 @@ class ModuleFileSharedCore {
508508
return info;
509509
}
510510

511+
/// Outputs information useful for diagnostics to \p out
512+
void outputDiagnosticInfo(llvm::raw_ostream &os) const;
513+
511514
// Out of line to avoid instantiation OnDiskChainedHashTable here.
512515
~ModuleFileSharedCore();
513516

test/Frontend/crash-in-user-code.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// CHECK: Stack dump:
1313
// CHECK-NEXT: Program arguments:
1414
// CHECK-NEXT: Swift version
15+
// CHECK-NEXT: Compiling with effective version
1516
// CHECK-NEXT: Contents of {{.*}}.filelist.txt:
1617
// CHECK-NEXT: ---
1718
// CHECK-NEXT: crash-in-user-code.swift

test/Frontend/crash.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,19 @@
22
// RUN: not --crash %target-swift-frontend -typecheck -debug-crash-after-parse -filelist %t.filelist.txt 2>&1 | %FileCheck %s
33

44
// Check that we see the contents of the input file list in the crash log.
5+
// CHECK-NOT: Compiling with {{.*}} while allowing modules with compiler errors enabled
56
// CHECK-LABEL: Stack dump
67
// CHECK-NEXT: Program arguments: {{.*swift(-frontend)?(c?)(\.exe)?}}
78
// CHECK-NEXT: Swift version
9+
// CHECK-NEXT: Compiling with effective version
810
// CHECK-NEXT: Contents of {{.*}}.filelist.txt:
911
// CHECK-NEXT: ---
1012
// CHECK-NEXT: test{{[\\/]}}Frontend{{[\\/]}}crash.swift{{$}}
1113
// CHECK-NEXT: ---
1214

13-
// Check that a message when allowing errors is output
1415
// RUN: not --crash %target-swift-frontend -typecheck -debug-crash-after-parse -experimental-allow-module-with-compiler-errors %s 2>&1 | %FileCheck -check-prefix CHECK-ALLOW %s
15-
// CHECK-ALLOW-LABEL: Stack dump
16-
// CHECK-ALLOW: While allowing modules with compiler errors enabled
16+
// CHECK-ALLOW: Program arguments: {{.*}} -experimental-allow-module-with-compiler-errors
17+
// CHECK-ALLOW: Compiling with effective version
1718

1819
func anchor() {}
1920
anchor()

test/Serialization/AllowErrors/crash-adds-message.swift

Lines changed: 0 additions & 16 deletions
This file was deleted.

test/Serialization/Recovery/crash-recovery.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ public class Sub: Base {
1313
}
1414

1515
// CHECK-CRASH: error: fatal error encountered while reading from module 'Lib'; please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the project
16-
// CHECK-CRASH: note: module 'Lib' full misc version is
17-
// CHECK-CRASH-4-NOT: note: compiling as
18-
// CHECK-CRASH-4_2: note: compiling as Swift 4.2, with 'Lib' built as Swift 4.1.50
19-
// CHECK-CRASH-LABEL: *** DESERIALIZATION FAILURE (please include this section in any bug report) ***
20-
// CHECK-CRASH: could not find 'disappearingMethod()' in parent class
16+
// CHECK-CRASH-4: Compiling with effective version 4.1.50
17+
// CHECK-CRASH-4_2: Compiling with effective version 4.2
2118
// CHECK-CRASH: While loading members for 'Sub' (in module 'Lib')
19+
// CHECK-CRASH-LABEL: *** DESERIALIZATION FAILURE ***
20+
// CHECK-CRASH: module 'Lib' with full misc version {{.*}}4.1.50
21+
// CHECK-CRASH: could not find 'disappearingMethod()' in parent class

0 commit comments

Comments
 (0)