Skip to content

Commit 599ba8b

Browse files
committed
Add all deserialization fatal output to the pretty stack trace
Rather than outputting diagnostics and to stderr, output all the extra information added when deserialization fatally fails to the pretty stack trace instead. Since the pretty stack trace is added to crash logs, this should avoid the dance of requesting the compiler output - Moves the previous "**** DESERIALIZATION FAILURE ..." output to the last pretty stack trace line - Removes the module and compiler version notes added to the fatal diagnostic - Adds a new effective compiler version line for all frontend failure. Somewhat duplicates the line from the driver, but adds in the effective version - Adds a new line for the full misc version of the module that failed. May double up with previous "While reading from ..." lines that are added in various deserialization methods, but better to have it twice than not at all
1 parent dd543e6 commit 599ba8b

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>
@@ -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) {
@@ -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)