Skip to content

Commit 3e4d01d

Browse files
authored
Merge pull request #37796 from bnbarham/5.5-cherry-pretty-stack
[5.5] Add all deserialization fatal output to the pretty stack trace
2 parents 325ca87 + fb92cfc commit 3e4d01d

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"
@@ -1952,6 +1953,23 @@ static void printTargetInfo(const CompilerInvocation &invocation,
19521953
out << "}\n";
19531954
}
19541955

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

2047-
Optional<llvm::PrettyStackTraceString> allowErrorsStackTrace;
2048-
if (Invocation.getFrontendOptions().AllowModuleWithCompilerErrors)
2049-
allowErrorsStackTrace.emplace("While allowing modules with compiler errors "
2050-
"enabled");
2065+
PrettyStackTraceFrontend frontendTrace(Invocation.getLangOptions());
20512066

20522067
// Make an array of PrettyStackTrace objects to dump the configuration files
20532068
// 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>
@@ -6302,7 +6280,7 @@ void ModuleFile::finishNormalConformance(NormalProtocolConformance *conformance,
63026280
uint64_t contextData) {
63036281
using namespace decls_block;
63046282

6305-
PrettyStackTraceModuleFile traceModule("While reading from", *this);
6283+
PrettyStackTraceModuleFile traceModule(*this);
63066284
PrettyStackTraceConformance trace("finishing conformance for",
63076285
conformance);
63086286
++NumNormalProtocolConformancesCompleted;
@@ -6718,9 +6696,3 @@ Optional<ForeignAsyncConvention> ModuleFile::maybeReadForeignAsyncConvention() {
67186696
completionHandlerErrorFlagParamIndex,
67196697
errorFlagPolarity);
67206698
}
6721-
6722-
void serialization::PrettyStackTraceModuleFile::outputModuleBuildInfo(
6723-
raw_ostream &os) const {
6724-
if (MF.compiledAllowingCompilerErrors())
6725-
os << " (built while allowing compiler errors)";
6726-
}

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) {
@@ -452,13 +450,31 @@ std::string ModuleFileSharedCore::Dependency::getPrettyPrintedPath() const {
452450
return output;
453451
}
454452

455-
void ModuleFileSharedCore::fatal(llvm::Error error) {
456-
logAllUnhandledErrors(std::move(error), llvm::errs(),
457-
"\n*** DESERIALIZATION FAILURE (please include this "
458-
"section in any bug report) ***\n");
453+
void ModuleFileSharedCore::fatal(llvm::Error error) const {
454+
llvm::SmallString<0> errorStr;
455+
llvm::raw_svector_ostream out(errorStr);
456+
457+
out << "*** DESERIALIZATION FAILURE ***\n";
458+
outputDiagnosticInfo(out);
459+
out << "\n";
460+
if (error) {
461+
handleAllErrors(std::move(error), [&](const llvm::ErrorInfoBase &ei) {
462+
ei.log(out);
463+
out << "\n";
464+
});
465+
}
466+
467+
llvm::PrettyStackTraceString trace(errorStr.c_str());
459468
abort();
460469
}
461470

471+
void ModuleFileSharedCore::outputDiagnosticInfo(llvm::raw_ostream &os) const {
472+
os << "module '" << Name << "' with full misc version '" << MiscVersion
473+
<< "'";
474+
if (Bits.IsAllowModuleWithCompilerErrorsEnabled)
475+
os << " (built with -experimental-allow-module-with-compiler-errors)";
476+
}
477+
462478
ModuleFileSharedCore::~ModuleFileSharedCore() { }
463479

464480
std::unique_ptr<ModuleFileSharedCore::SerializedDeclTable>

lib/Serialization/ModuleFileSharedCore.h

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

366366
/// Emits one last diagnostic, logs the error, and then aborts for the stack
367367
/// trace.
368-
LLVM_ATTRIBUTE_NORETURN static void fatal(llvm::Error error);
369-
void fatalIfNotSuccess(llvm::Error error) {
368+
LLVM_ATTRIBUTE_NORETURN void fatal(llvm::Error error) const;
369+
void fatalIfNotSuccess(llvm::Error error) const {
370370
if (error)
371371
fatal(std::move(error));
372372
}
373-
template <typename T> T fatalIfUnexpected(llvm::Expected<T> expected) {
373+
template <typename T> T fatalIfUnexpected(llvm::Expected<T> expected) const {
374374
if (expected)
375375
return std::move(expected.get());
376376
fatal(expected.takeError());
@@ -502,6 +502,9 @@ class ModuleFileSharedCore {
502502
return info;
503503
}
504504

505+
/// Outputs information useful for diagnostics to \p out
506+
void outputDiagnosticInfo(llvm::raw_ostream &os) const;
507+
505508
// Out of line to avoid instantiation OnDiskChainedHashTable here.
506509
~ModuleFileSharedCore();
507510

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)