From cf8d7ae8e604f8b56a09f1fedaf3c4dc65ea970c Mon Sep 17 00:00:00 2001 From: Leonard Grey Date: Mon, 4 May 2026 17:40:59 -0400 Subject: [PATCH 1/2] [lldb][Windows] Require exact match in LLDBMemoryReader::resolvePointerAsSymbol LLDBMemoryReader::resolvePointerAsSymbol will return a symbol if its argument points anywhere inside it. When we have sparse symbols for an image (for example, just COFF exports), we assume that the size of a given symbol is the distance between it and the next known symbol. However, this extent can actually include any number of private symbols. Because of this, multiple symbols resolve to the name of the preceding public symbol, and the last one read can overwrite the others in the `TypeRefBuilder`'s cache. This change adds a requirement on Windows that the pointer match the *start* of a symbol to keep the cache from being stomped. See https://github.com/swiftlang/llvm-project/issues/12891 for details. (cherry picked from commit 565e24fcd2cd450bb6834dfda9dc6b4ca041dd07) --- .../Plugins/LanguageRuntime/Swift/LLDBMemoryReader.cpp | 3 +++ lldb/test/Shell/SymbolFile/NativePDB/swift-frame-var.test | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.cpp index b78adcddae734..5c112f7b54d46 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.cpp @@ -204,6 +204,9 @@ LLDBMemoryReader::resolvePointerAsSymbol(swift::remote::RemoteAddress address) { } if (auto *symbol = addr.CalculateSymbolContextSymbol()) { + if (triple.isOSWindows() && + addr.GetFileAddress() != symbol->GetAddressRef().GetFileAddress()) + return {}; auto mangledName = symbol->GetMangled().GetMangledName().GetStringRef(); // MemoryReader requires this to be a Swift symbol. LLDB can also be // aware of local symbols, so avoid returning those. diff --git a/lldb/test/Shell/SymbolFile/NativePDB/swift-frame-var.test b/lldb/test/Shell/SymbolFile/NativePDB/swift-frame-var.test index 213f5ad09396d..911ee976932c5 100644 --- a/lldb/test/Shell/SymbolFile/NativePDB/swift-frame-var.test +++ b/lldb/test/Shell/SymbolFile/NativePDB/swift-frame-var.test @@ -43,6 +43,8 @@ func main() { var myResult: Result = .success(42) var myBox: Box = Box(value: 99) var myPair: Pair = .first(7) + var myDictionary: [Int: String] = [1: "one", 2: "two"] + var mySet: Set = [1, 2, 3] let constInt: Int = 100 let constInt8: Int8 = -42 let constUInt16: UInt16 = 1000 @@ -50,14 +52,14 @@ func main() { let constString: String = "world" print(myInt32, myBool, myUInt64, myFloat, myDouble, myString, myPoint, myDirection, myOptional, myNestedOptional, myArray, - myOptionalArray, myResult, myBox, myPair, + myOptionalArray, myResult, myBox, myPair, myDictionary, mySet, constInt, constInt8, constUInt16, constBool, constString) } main() #--- commands.input -b main.swift:41 +b main.swift:43 run frame variable @@ -78,6 +80,8 @@ frame variable # CHECK: (Result) myResult = success # CHECK: (main.Box) myBox = (value = 99) # CHECK: (main.Pair) myPair = first +# CHECK: ([Int : String]) myDictionary = 2 key/value pairs +# CHECK: (Set) mySet = 3 values # Local constants # CHECK: (Int) constInt = 100 # CHECK: (Int8) constInt8 = -42 From 73075fe354d41f22bf0cd10ac7a2fde715dde27b Mon Sep 17 00:00:00 2001 From: Leonard Grey Date: Tue, 5 May 2026 12:56:47 -0400 Subject: [PATCH 2/2] Add comment, un-xfail tests (cherry picked from commit 08f4dd4e1f534bcd5c83002bca43f9cf863107e3) (cherry picked from commit cccc4171b8ae271bea03a68de5064dd834c08ad5) --- .../source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.cpp | 4 ++++ lldb/test/API/lang/swift/observation/TestSwiftObservation.py | 1 - lldb/test/API/lang/swift/regex/TestSwiftRegex.py | 2 -- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.cpp index 5c112f7b54d46..24967c37e702e 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/LLDBMemoryReader.cpp @@ -204,6 +204,10 @@ LLDBMemoryReader::resolvePointerAsSymbol(swift::remote::RemoteAddress address) { } if (auto *symbol = addr.CalculateSymbolContextSymbol()) { + // Require `addr` to point to the beginning of the symbol since the + // COFF export table is sparse and we can inadvertently misattribute + // private symbols to the preceding public symbol. + // See https://github.com/swiftlang/llvm-project/issues/12891 if (triple.isOSWindows() && addr.GetFileAddress() != symbol->GetAddressRef().GetFileAddress()) return {}; diff --git a/lldb/test/API/lang/swift/observation/TestSwiftObservation.py b/lldb/test/API/lang/swift/observation/TestSwiftObservation.py index e57ae01a3cf2f..33a3dd4e08dd5 100644 --- a/lldb/test/API/lang/swift/observation/TestSwiftObservation.py +++ b/lldb/test/API/lang/swift/observation/TestSwiftObservation.py @@ -8,7 +8,6 @@ class TestSwiftObservation(TestBase): NO_DEBUG_INFO_TESTCASE = True @swiftTest - @expectedFailureWindows def test(self): """Test that types with private discriminators read from the file cache work""" self.build() diff --git a/lldb/test/API/lang/swift/regex/TestSwiftRegex.py b/lldb/test/API/lang/swift/regex/TestSwiftRegex.py index f317ca1473122..32a8d3ef52c90 100644 --- a/lldb/test/API/lang/swift/regex/TestSwiftRegex.py +++ b/lldb/test/API/lang/swift/regex/TestSwiftRegex.py @@ -26,7 +26,6 @@ def setUp(self): @swiftTest @skipIf(macos_version=["<", "13"]) - @expectedFailureWindows def test_swift_regex_frame_var(self): """Test frame variable support for Swift regexes.""" self.build() @@ -63,7 +62,6 @@ def test_swift_regex_frame_var_desc(self): @swiftTest @skipIf(macos_version=["<", "13"]) - @expectedFailureWindows def test_swift_regex_expr(self): """Test expression support for Swift regexes.""" self.build()