llvm / llvm/llvm-project

[pdb] MSF writer will incorrectly use pages that are reserved for the Free Page Map.

Open
#206,436 1 comment 0 reactions 0 assignees View on GitHub
crash debuginfo
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

As reported by @sivadeilra it seems LLVM's PDB/MSF writer will sometimes use pages that are reserved for the FPM.

Adding an assert like this:

```
diff --git a/llvm/lib/DebugInfo/MSF/MSFBuilder.cpp b/llvm/lib/DebugInfo/MSF/MSFBuilder.cpp
index 7890bcce6c7c..1a62aad931a7 100644
--- a/llvm/lib/DebugInfo/MSF/MSFBuilder.cpp
+++ b/llvm/lib/DebugInfo/MSF/MSFBuilder.cpp
@@ -134,6 +134,10 @@ Error MSFBuilder::allocateBlocks(uint32_t NumBlocks,
do {
assert(Block != -1 && "We ran out of Blocks!");

+ assert(Block % BlockSize != kFreePageMap0Block &&
+ Block % BlockSize != kFreePageMap1Block &&
+ "don't write on the FPM pages");
+
uint32_t NextBlock = static_cast(Block);
Blocks[I++] = NextBlock;
FreeBlocks.reset(NextBlock);
```

triggers when building a large pdb, such as chrome.dll.pdb:

(In this case BlockSize=8192 and Block=409601=8192*50+1)

```
lld-link: /work/llvm-project/llvm/lib/DebugInfo/MSF/MSFBuilder.cpp:139: Error llvm::msf::MSFBuilder::allocateBlocks(uint32_t, MutableArrayRef): Assertion `Block % BlockSize != kFreePageMap0Block && Block % BlockSize != kFreePageMap1Block && "don't write on the FPM pages"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and instructions to reproduce the bug.
Stack dump:
0. Program arguments: ../../third_party/llvm-build/Release+Asserts/bin/lld-link --rsp-quoting=posix /OUT:./chrome.dll /nologo -libpath:../../third_party/llvm-build/Release+Asserts/lib/clang/23/lib/windows /winsysroot:../../third_party/depot_tools/win_toolchain/vs_files/e66617bc68 /MACHINE:X64 /IMPLIB:./chrome.dll.lib /DLL /PDB:./chrome.dll.pdb @./chrome.dll.rsp
#0 0x000055f9161562c8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (../../third_party/llvm-build/Release+Asserts/bin/lld-link+0x9202c8)
#1 0x000055f9161530a1 llvm::sys::RunSignalHandlers() (../../third_party/llvm-build/Release+Asserts/bin/lld-link+0x91d0a1)
#2 0x000055f916157411 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
#3 0x00007f7a99e40e30 (/usr/lib/x86_64-linux-gnu/libc.so.6+0x40e30)
#4 0x00007f7a99e97d1c __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
#5 0x00007f7a99e40d02 raise ./signal/../sysdeps/posix/raise.c:27:6
#6 0x00007f7a99e284b2 abort ./stdlib/abort.c:85:3
#7 0x00007f7a99e28424 __assert_perror_fail ./assert/assert-perr.c:31:1
#8 0x000055f91a2847e9 llvm::msf::MSFBuilder::allocateBlocks(unsigned int, llvm::MutableArrayRef) (../../third_party/llvm-build/Release+Asserts/bin/lld-link+0x4a4e7e9)
#9 0x000055f91a285075 llvm::msf::MSFBuilder::addStream(unsigned int) (../../third_party/llvm-build/Release+Asserts/bin/lld-link+0x4a4f075)
#10 0x000055f91a1e7b21 llvm::pdb::DbiModuleDescriptorBuilder::finalizeMsfLayout() (../../third_party/llvm-build/Release+Asserts/bin/lld-link+0x49b1b21)
#11 0x000055f91a1eb244 llvm::pdb::DbiStreamBuilder::finalizeMsfLayout() (../../third_party/llvm-build/Release+Asserts/bin/lld-link+0x49b5244)
#12 0x000055f91a1ff8a3 llvm::pdb::PDBFileBuilder::finalizeMsfLayout() (../../third_party/llvm-build/Release+Asserts/bin/lld-link+0x49c98a3)
#13 0x000055f91a200f3e llvm::pdb::PDBFileBuilder::commit(llvm::StringRef, llvm::codeview::GUID*) (../../third_party/llvm-build/Release+Asserts/bin/lld-link+0x49caf3e)
#14 0x000055f91626e3d0 lld::coff::createPDB(lld::coff::COFFLinkerContext&, llvm::ArrayRef, llvm::codeview::DebugInfo*) (../../third_party/llvm-build/Release+Asserts/bin/lld-link+0xa383d0)
#15 0x000055f9162179c8 (anonymous namespace)::Writer::run() Writer.cpp:0:0
#16 0x000055f91620e22b lld::coff::writeResult(lld::coff::COFFLinkerContext&) (../../third_party/llvm-build/Release+Asserts/bin/lld-link+0x9d822b)
#17 0x000055f9161b554a lld::coff::LinkerDriver::linkerMain(llvm::ArrayRef) (../../third_party/llvm-build/Release+Asserts/bin/lld-link+0x97f54a)
#18 0x000055f9161abd7e lld::coff::link(llvm::ArrayRef, llvm::raw_ostream&, llvm::raw_ostream&, bool, bool) (../../third_party/llvm-build/Release+Asserts/bin/lld-link+0x975d7e)
#19 0x000055f916196cd7 lld::unsafeLldMain(llvm::ArrayRef, llvm::raw_ostream&, llvm::raw_ostream&, llvm::ArrayRef, bool) (../../third_party/llvm-build/Release+Asserts/bin/lld-link+0x960cd7)
#20 0x000055f9160d48ee lld_main(int, char**, llvm::ToolContext const&) (../../third_party/llvm-build/Release+Asserts/bin/lld-link+0x89e8ee)
#21 0x000055f9160d4d3a main (../../third_party/llvm-build/Release+Asserts/bin/lld-link+0x89ed3a)
#22 0x00007f7a99e29f77 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
#23 0x00007f7a99e2a027 call_init ./csu/../csu/libc-start.c:128:20
#24 0x00007f7a99e2a027 __libc_start_main ./csu/../csu/libc-start.c:347:5
#25 0x000055f9160d4591 _start (../../third_party/llvm-build/Release+Asserts/bin/lld-link+0x89e591)
```

Contributor guide

Open the contributing guide

Research direction

Start in llvm/lib/DebugInfo/MSF/MSFBuilder.cpp, especially MSFBuilder::allocateBlocks, and trace how blocks are selected during addStream and PDB layout finalization. Reproduce the assertion with a large PDB such as chrome.dll.pdb, then verify that allocated blocks no longer overlap the Free Page Map pages and that the large-PDB link completes.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.