Skip to content

Commit 8484c61

Browse files
committed
[debuginfo][codeview] avoid using line zero artificial location for traps when emitting codeview
This fixes an issue where the debug locations for Swift traps were dropped in the produced PDB files, as they were pointing to line 0 I validated this on a sample project using WinDbgx, which can now correctly trap on the same line in multiple places
1 parent 0c2425f commit 8484c61

File tree

5 files changed

+39
-8
lines changed

5 files changed

+39
-8
lines changed

include/swift/AST/IRGenOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,10 @@ class IRGenOptions {
642642
bool hasMultipleIRGenThreads() const { return !UseSingleModuleLLVMEmission && NumThreads > 1; }
643643
bool shouldPerformIRGenerationInParallel() const { return !UseSingleModuleLLVMEmission && NumThreads != 0; }
644644
bool hasMultipleIGMs() const { return hasMultipleIRGenThreads(); }
645+
646+
bool isDebugInfoCodeView() const {
647+
return DebugInfoFormat == IRGenDebugInfoFormat::CodeView;
648+
}
645649
};
646650

647651
} // end namespace swift

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2661,12 +2661,18 @@ void IRGenDebugInfoImpl::addFailureMessageToCurrentLoc(IRBuilder &Builder,
26612661
else {
26622662
std::string FuncName = "Swift runtime failure: ";
26632663
FuncName += failureMsg;
2664-
llvm::DIFile *File = getOrCreateFile({}, {});
2664+
// CodeView consumers do not correctly handle an artificially generated
2665+
// file, thus use the original location's file as the file for the debug
2666+
// function, and prevent reuse of this debug function.
2667+
bool useCompilerGeneratedFile = !Opts.isDebugInfoCodeView();
2668+
llvm::DIFile *File =
2669+
useCompilerGeneratedFile ? getOrCreateFile({}, {}) : TrapLoc->getFile();
26652670
TrapSP = DBuilder.createFunction(
26662671
File, FuncName, StringRef(), File, 0,
26672672
DIFnTy, 0, llvm::DINode::FlagArtificial,
26682673
llvm::DISubprogram::SPFlagDefinition, nullptr, nullptr, nullptr);
2669-
RuntimeErrorFnCache.insert({failureMsg, llvm::TrackingMDNodeRef(TrapSP)});
2674+
if (useCompilerGeneratedFile)
2675+
RuntimeErrorFnCache.insert({failureMsg, llvm::TrackingMDNodeRef(TrapSP)});
26702676
}
26712677

26722678
ScopeCache[TrapSc] = llvm::TrackingMDNodeRef(TrapSP);
@@ -2675,7 +2681,11 @@ void IRGenDebugInfoImpl::addFailureMessageToCurrentLoc(IRBuilder &Builder,
26752681
assert(parentScopesAreSane(TrapSc) && "parent scope sanity check failed");
26762682

26772683
// Wrap the existing TrapLoc into the failure function.
2678-
auto DL = llvm::DILocation::get(IGM.getLLVMContext(), 0, 0, TrapSP, TrapLoc);
2684+
// Line 0 is invalid in CodeView, so use the line and column from the original
2685+
// trap location.
2686+
auto DL = llvm::DILocation::get(
2687+
IGM.getLLVMContext(), Opts.isDebugInfoCodeView() ? TrapLoc.getLine() : 0,
2688+
Opts.isDebugInfoCodeView() ? TrapLoc.getCol() : 0, TrapSP, TrapLoc);
26792689
Builder.SetCurrentDebugLocation(DL);
26802690
}
26812691

lib/IRGen/IRGenFunction.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,20 @@ Address IRGenFunction::emitAddressAtOffset(llvm::Value *base, Offset offset,
445445

446446
llvm::CallInst *IRBuilder::CreateNonMergeableTrap(IRGenModule &IGM,
447447
StringRef failureMsg) {
448+
if (IGM.DebugInfo && IGM.getOptions().isDebugInfoCodeView()) {
449+
auto TrapLoc = getCurrentDebugLocation();
450+
// Line 0 is invalid in CodeView, so create a new location that uses the
451+
// line and column from the inlined location of the trap, that should
452+
// correspond to its original source location.
453+
if (TrapLoc.getLine() == 0 && TrapLoc.getInlinedAt()) {
454+
auto DL = llvm::DILocation::getDistinct(
455+
IGM.getLLVMContext(), TrapLoc.getInlinedAt()->getLine(),
456+
TrapLoc.getInlinedAt()->getColumn(), TrapLoc.getScope(),
457+
TrapLoc.getInlinedAt());
458+
SetCurrentDebugLocation(DL);
459+
}
460+
}
461+
448462
if (IGM.IRGen.Opts.shouldOptimize()) {
449463
// Emit unique side-effecting inline asm calls in order to eliminate
450464
// the possibility that an LLVM optimization or code generation pass

test/DebugInfo/doubleinlines.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,13 @@ func callCondFail(arg: Builtin.Int1, msg: Builtin.RawPointer) {
1212

1313
// CHECK: define hidden swiftcc void @"$s13DoubleInlines12callCondFail3arg3msgyBi1__BptF"{{.*}} !dbg ![[FUNC:.*]] {
1414
// CHECK: tail call void asm sideeffect "", "n"(i32 0) #3, !dbg ![[SCOPEONE:.*]]
15+
// CHECK: tail call void @llvm.trap(), !dbg ![[LOCTRAP:.*]]
16+
1517
// CHECK: ![[FUNCSCOPEOTHER:.*]] = distinct !DISubprogram(name: "condFail",{{.*}}
16-
// CHECK: ![[SCOPEONE]] = !DILocation(line: 0, scope: ![[SCOPETWO:.*]], inlinedAt: ![[SCOPETHREE:.*]])
18+
// CHECK: ![[SCOPEONE]] = distinct !DILocation(line: 6, scope: ![[SCOPETWO:.*]], inlinedAt: ![[SCOPETHREE:.*]])
1719
// CHECK: ![[SCOPETHREE]] = !DILocation(line: 6, scope: ![[FUNCSCOPE:.*]])
1820
// CHECK: ![[FUNCSCOPE:[0-9]+]] = distinct !DILexicalBlock(scope: ![[FUNC]],
21+
// CHECK: ![[LOCTRAP]] = !DILocation(line: 6, scope: ![[SCOPETRAP:.*]], inlinedAt: ![[SCOPEONE]])
22+
// CHECK: ![[SCOPETRAP]] = distinct !DISubprogram(name: "Swift runtime failure: unknown program error"
1923

2024
import Builtin

test/DebugInfo/linetable-codeview.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,10 @@ func foo() {
7878

7979
// CHECK-DAG: ![[ADD]] = !DILocation(line: 6, scope:
8080
// CHECK-DAG: ![[DIV]] = !DILocation(line: 7, scope:
81-
// FIXME: The location of ``@llvm.trap`` should be in Integers.swift.gyb
82-
// instead of being artificial.
83-
// CHECK: ![[INLINEDADD]] = !DILocation(line: 0, scope: ![[FAILURE_FUNC:[0-9]+]], inlinedAt: ![[INLINELOC:[0-9]+]]
81+
82+
// CHECK: ![[INLINEDADD]] = !DILocation(line: 6, scope: ![[FAILURE_FUNC:[0-9]+]], inlinedAt: ![[INLINELOC:[0-9]+]]
8483
// CHECK-DAG: !{{.*}} = distinct !DISubprogram(name: "Swift runtime failure: arithmetic overflow", scope: {{.*}}, flags: DIFlagArtificial, spFlags: DISPFlagDefinition, {{.*}})
85-
// CHECK-DAG: ![[INLINELOC]] = !DILocation(line: 0, scope: !{{[0-9]+}}, inlinedAt: ![[ADD]]
84+
// CHECK-DAG: ![[INLINELOC]] = distinct !DILocation(line: 6, scope: !{{[0-9]+}}, inlinedAt: ![[ADD]]
8685

8786
// NOTE: These prologue instructions are given artificial line locations for
8887
// LLDB, but for CodeView they should have the location of the function

0 commit comments

Comments
 (0)