From c4bd263d19e4a73dbb409826ad7bb1549044d125 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Wed, 24 Sep 2025 09:59:07 -0700 Subject: [PATCH 01/17] [Debug] Add pointer based stringForPrintObject Adds an overload of `stringForPrintObject` which takes a pointer and mangled typename as arguments. This will be used to improve performance and resilience of `po` in lldb. The pointer and mangled typename are used to construct an `Any` value, which is then passed into the primary implementation of `stringForPrintObject`. This allows calling `stringForPrintObject` without having to first construct a context that contains all necessary Swift modules. This will improve speed, and also resilience when modules cannot be loaded for whatever reason. --- stdlib/public/core/DebuggerSupport.swift | 20 ++++++++++++++++++++ test/stdlib/DebuggerSupport.swift | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/stdlib/public/core/DebuggerSupport.swift b/stdlib/public/core/DebuggerSupport.swift index 93efe80075c8b..02c248a6e3e16 100644 --- a/stdlib/public/core/DebuggerSupport.swift +++ b/stdlib/public/core/DebuggerSupport.swift @@ -328,6 +328,26 @@ public enum _DebuggerSupport { return target } + + public static func stringForPrintObject(_ pointer: UnsafeRawPointer?, mangledTypeName: String) -> String { + guard let pointer else { return "invalid value pointer" } + + guard let type = + unsafe _getTypeByMangledNameInContext( + mangledTypeName, + UInt(mangledTypeName.count), + genericContext: nil, + genericArguments: nil) + else { + return "invalid type \(mangledTypeName)" + } + + func loadPointer(type: T.Type) -> Any { + unsafe pointer.load(as: T.self) + } + let anyValue = _openExistential(type, do: loadPointer) + return stringForPrintObject(anyValue) + } } public func _stringForPrintObject(_ value: Any) -> String { diff --git a/test/stdlib/DebuggerSupport.swift b/test/stdlib/DebuggerSupport.swift index 8747680505ced..23f7b94ce8355 100644 --- a/test/stdlib/DebuggerSupport.swift +++ b/test/stdlib/DebuggerSupport.swift @@ -108,6 +108,28 @@ if #available(SwiftStdlib 6.1, *) { } } +func _expectStringForPrintObject(_ pointer: UnsafePointer, output: String) { + let mangledTypeName = _mangledTypeName(T.self) + let printed = _DebuggerSupport.stringForPrintObject(UnsafeRawPointer(pointer), mangledTypeName: mangledTypeName!) + expectEqual(printed, output) +} + +StringForPrintObjectTests.test("PointerWithMangledTypeName") { + var num = 33 + _expectStringForPrintObject(&num, output: "33\n") + + var val1 = StructWithMembers() + _expectStringForPrintObject(&val1, output: "▿ StructWithMembers\n - a : 1\n - b : \"Hello World\"\n") + var val2 = StructWithMembersAndDescription() + _expectStringForPrintObject(&val2, output: "Hello World\n") + + let obj = ClassWithMembers() + let pointer = unsafeBitCast(obj, to: UnsafeRawPointer.self) + let mangledTypeName = _mangledTypeName(ClassWithMembers.self) + let printed = _DebuggerSupport.stringForPrintObject(pointer, mangledTypeName: mangledTypeName!) + expectTrue(printed.hasPrefix(" Date: Tue, 14 Oct 2025 13:02:30 -0700 Subject: [PATCH 02/17] Add test for generic value (Optional) --- test/stdlib/DebuggerSupport.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/stdlib/DebuggerSupport.swift b/test/stdlib/DebuggerSupport.swift index 23f7b94ce8355..4a26fe8b49d45 100644 --- a/test/stdlib/DebuggerSupport.swift +++ b/test/stdlib/DebuggerSupport.swift @@ -123,6 +123,10 @@ StringForPrintObjectTests.test("PointerWithMangledTypeName") { var val2 = StructWithMembersAndDescription() _expectStringForPrintObject(&val2, output: "Hello World\n") + var val3: StructWithMembers? = StructWithMembers() + _expectStringForPrintObject(&val3, + output: "▿ Optional\n ▿ some : StructWithMembers\n - a : 1\n - b : \"Hello World\"\n") + let obj = ClassWithMembers() let pointer = unsafeBitCast(obj, to: UnsafeRawPointer.self) let mangledTypeName = _mangledTypeName(ClassWithMembers.self) From 581580fd7f1ed2cbb2155b884e0c15de3c18aac4 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Mon, 10 Nov 2025 09:28:07 -0800 Subject: [PATCH 03/17] Change return type to (Bool, String) --- stdlib/public/core/DebuggerSupport.swift | 15 +++-- test/stdlib/DebuggerSupport.swift | 75 ++++++++++++++++-------- 2 files changed, 63 insertions(+), 27 deletions(-) diff --git a/stdlib/public/core/DebuggerSupport.swift b/stdlib/public/core/DebuggerSupport.swift index 02c248a6e3e16..7a93ad5a3057b 100644 --- a/stdlib/public/core/DebuggerSupport.swift +++ b/stdlib/public/core/DebuggerSupport.swift @@ -329,8 +329,15 @@ public enum _DebuggerSupport { return target } - public static func stringForPrintObject(_ pointer: UnsafeRawPointer?, mangledTypeName: String) -> String { - guard let pointer else { return "invalid value pointer" } + // Print an object or value without the caller having a concrete type. + // + // For simplicity of data handling in LLDB avoids using an enum return type, + // using (Bool, String) instead of Optional. + @available(SwiftStdlib 6.3, *) + public static func stringForPrintObject(_ pointer: UnsafeRawPointer?, mangledTypeName: String) -> (Bool, String) { + guard let pointer = unsafe pointer else { + return (false, "invalid pointer") + } guard let type = unsafe _getTypeByMangledNameInContext( @@ -339,14 +346,14 @@ public enum _DebuggerSupport { genericContext: nil, genericArguments: nil) else { - return "invalid type \(mangledTypeName)" + return (false, "type not found for mangled name: \(mangledTypeName)") } func loadPointer(type: T.Type) -> Any { unsafe pointer.load(as: T.self) } let anyValue = _openExistential(type, do: loadPointer) - return stringForPrintObject(anyValue) + return (true, stringForPrintObject(anyValue)) } } diff --git a/test/stdlib/DebuggerSupport.swift b/test/stdlib/DebuggerSupport.swift index 4a26fe8b49d45..a50cb0a0bba8e 100644 --- a/test/stdlib/DebuggerSupport.swift +++ b/test/stdlib/DebuggerSupport.swift @@ -10,6 +10,16 @@ struct StructWithMembers { var b = "Hello World" } +struct StructWithMembersAndDescription: CustomStringConvertible { + var a = 1 + var description: String { "Hello World" } +} + +struct StructIsNonCopyable: ~Copyable { + var a = 1 + var b = "Hello World" +} + class ClassWithMembers { var a = 1 var b = "Hello World" @@ -108,30 +118,49 @@ if #available(SwiftStdlib 6.1, *) { } } +@available(SwiftStdlib 6.3, *) func _expectStringForPrintObject(_ pointer: UnsafePointer, output: String) { - let mangledTypeName = _mangledTypeName(T.self) - let printed = _DebuggerSupport.stringForPrintObject(UnsafeRawPointer(pointer), mangledTypeName: mangledTypeName!) - expectEqual(printed, output) -} - -StringForPrintObjectTests.test("PointerWithMangledTypeName") { - var num = 33 - _expectStringForPrintObject(&num, output: "33\n") - - var val1 = StructWithMembers() - _expectStringForPrintObject(&val1, output: "▿ StructWithMembers\n - a : 1\n - b : \"Hello World\"\n") - var val2 = StructWithMembersAndDescription() - _expectStringForPrintObject(&val2, output: "Hello World\n") - - var val3: StructWithMembers? = StructWithMembers() - _expectStringForPrintObject(&val3, - output: "▿ Optional\n ▿ some : StructWithMembers\n - a : 1\n - b : \"Hello World\"\n") - - let obj = ClassWithMembers() - let pointer = unsafeBitCast(obj, to: UnsafeRawPointer.self) - let mangledTypeName = _mangledTypeName(ClassWithMembers.self) - let printed = _DebuggerSupport.stringForPrintObject(pointer, mangledTypeName: mangledTypeName!) - expectTrue(printed.hasPrefix("\n ▿ some : StructWithMembers\n - a : 1\n - b : \"Hello World\"\n") + + do { + var val4 = StructIsNonCopyable() + withUnsafeBytes(of: &val4) { bytes in + let mangledTypeName = _mangledTypeName(StructIsNonCopyable.self) + let (success, printed) = + _DebuggerSupport.stringForPrintObject(bytes.baseAddress!, mangledTypeName: mangledTypeName!) + expectFalse(success) + expectEqual(printed, "type not found for mangled name: \(mangledTypeName!)") + } + } + + do { + let obj = ClassWithMembers() + let pointer = unsafeBitCast(obj, to: UnsafeRawPointer.self) + let mangledTypeName = _mangledTypeName(ClassWithMembers.self) + let (success, printed) = _DebuggerSupport.stringForPrintObject(pointer, mangledTypeName: mangledTypeName!) + expectTrue(success) + expectEqual(printed.hasPrefix(" Date: Tue, 11 Nov 2025 13:52:26 -0800 Subject: [PATCH 04/17] Remove StructWithMembersAndDescription --- test/stdlib/DebuggerSupport.swift | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/stdlib/DebuggerSupport.swift b/test/stdlib/DebuggerSupport.swift index a50cb0a0bba8e..5255e719b22fa 100644 --- a/test/stdlib/DebuggerSupport.swift +++ b/test/stdlib/DebuggerSupport.swift @@ -134,15 +134,13 @@ if #available(SwiftStdlib 6.3, *) { var val1 = StructWithMembers() _expectStringForPrintObject(&val1, output: "▿ StructWithMembers\n - a : 1\n - b : \"Hello World\"\n") - var val2 = StructWithMembersAndDescription() - _expectStringForPrintObject(&val2, output: "Hello World\n") - var val3: StructWithMembers? = StructWithMembers() + var val2: StructWithMembers? = StructWithMembers() _expectStringForPrintObject(&val3, output: "▿ Optional\n ▿ some : StructWithMembers\n - a : 1\n - b : \"Hello World\"\n") do { - var val4 = StructIsNonCopyable() + var val3 = StructIsNonCopyable() withUnsafeBytes(of: &val4) { bytes in let mangledTypeName = _mangledTypeName(StructIsNonCopyable.self) let (success, printed) = From c554d847253b79acb4236f4d8b678651b80f7c62 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 11 Nov 2025 15:43:22 -0800 Subject: [PATCH 05/17] Fix variable references --- test/stdlib/DebuggerSupport.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/stdlib/DebuggerSupport.swift b/test/stdlib/DebuggerSupport.swift index 5255e719b22fa..19b4106d1d441 100644 --- a/test/stdlib/DebuggerSupport.swift +++ b/test/stdlib/DebuggerSupport.swift @@ -136,12 +136,12 @@ if #available(SwiftStdlib 6.3, *) { _expectStringForPrintObject(&val1, output: "▿ StructWithMembers\n - a : 1\n - b : \"Hello World\"\n") var val2: StructWithMembers? = StructWithMembers() - _expectStringForPrintObject(&val3, + _expectStringForPrintObject(&val2, output: "▿ Optional\n ▿ some : StructWithMembers\n - a : 1\n - b : \"Hello World\"\n") do { var val3 = StructIsNonCopyable() - withUnsafeBytes(of: &val4) { bytes in + withUnsafeBytes(of: &val3) { bytes in let mangledTypeName = _mangledTypeName(StructIsNonCopyable.self) let (success, printed) = _DebuggerSupport.stringForPrintObject(bytes.baseAddress!, mangledTypeName: mangledTypeName!) From 18939b395aab57165265d2b36f56b9fb729ed757 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 11 Nov 2025 15:45:43 -0800 Subject: [PATCH 06/17] Remove unintentional addition --- test/stdlib/DebuggerSupport.swift | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/stdlib/DebuggerSupport.swift b/test/stdlib/DebuggerSupport.swift index 19b4106d1d441..f80f5c1cc5d50 100644 --- a/test/stdlib/DebuggerSupport.swift +++ b/test/stdlib/DebuggerSupport.swift @@ -10,11 +10,6 @@ struct StructWithMembers { var b = "Hello World" } -struct StructWithMembersAndDescription: CustomStringConvertible { - var a = 1 - var description: String { "Hello World" } -} - struct StructIsNonCopyable: ~Copyable { var a = 1 var b = "Hello World" From 31834f9b1038dec78a527e9ea9deeedf213e2104 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 11 Nov 2025 20:01:30 -0800 Subject: [PATCH 07/17] Update abi tests --- test/abi/Inputs/macOS/arm64/stdlib/baseline | 1 + test/abi/Inputs/macOS/arm64/stdlib/baseline-asserts | 1 + test/abi/Inputs/macOS/x86_64/stdlib/baseline | 1 + test/abi/Inputs/macOS/x86_64/stdlib/baseline-asserts | 1 + 4 files changed, 4 insertions(+) diff --git a/test/abi/Inputs/macOS/arm64/stdlib/baseline b/test/abi/Inputs/macOS/arm64/stdlib/baseline index 7fa9a942d9065..1c5fd7891dd8f 100644 --- a/test/abi/Inputs/macOS/arm64/stdlib/baseline +++ b/test/abi/Inputs/macOS/arm64/stdlib/baseline @@ -6815,6 +6815,7 @@ _$ss16TextOutputStreamPsE11_writeASCIIyySRys5UInt8VGF _$ss16TextOutputStreamPsE5_lockyyF _$ss16TextOutputStreamPsE7_unlockyyF _$ss16TextOutputStreamTL +_$ss16_DebuggerSupportO20stringForPrintObject_15mangledTypeNameSb_SStSVSg_SStFZ _$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ _$ss16_DebuggerSupportOMa _$ss16_DebuggerSupportOMn diff --git a/test/abi/Inputs/macOS/arm64/stdlib/baseline-asserts b/test/abi/Inputs/macOS/arm64/stdlib/baseline-asserts index 4807b19909ef1..e3a496b13ffe4 100644 --- a/test/abi/Inputs/macOS/arm64/stdlib/baseline-asserts +++ b/test/abi/Inputs/macOS/arm64/stdlib/baseline-asserts @@ -6815,6 +6815,7 @@ _$ss16TextOutputStreamPsE11_writeASCIIyySRys5UInt8VGF _$ss16TextOutputStreamPsE5_lockyyF _$ss16TextOutputStreamPsE7_unlockyyF _$ss16TextOutputStreamTL +_$ss16_DebuggerSupportO20stringForPrintObject_15mangledTypeNameSb_SStSVSg_SStFZ _$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ _$ss16_DebuggerSupportOMa _$ss16_DebuggerSupportOMn diff --git a/test/abi/Inputs/macOS/x86_64/stdlib/baseline b/test/abi/Inputs/macOS/x86_64/stdlib/baseline index bc79fe5f89879..cbcfa402180bb 100644 --- a/test/abi/Inputs/macOS/x86_64/stdlib/baseline +++ b/test/abi/Inputs/macOS/x86_64/stdlib/baseline @@ -6836,6 +6836,7 @@ _$ss16TextOutputStreamPsE11_writeASCIIyySRys5UInt8VGF _$ss16TextOutputStreamPsE5_lockyyF _$ss16TextOutputStreamPsE7_unlockyyF _$ss16TextOutputStreamTL +_$ss16_DebuggerSupportO20stringForPrintObject_15mangledTypeNameSb_SStSVSg_SStFZ _$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ _$ss16_DebuggerSupportOMa _$ss16_DebuggerSupportOMn diff --git a/test/abi/Inputs/macOS/x86_64/stdlib/baseline-asserts b/test/abi/Inputs/macOS/x86_64/stdlib/baseline-asserts index ba9fb06fe7c5a..d909229e8c72c 100644 --- a/test/abi/Inputs/macOS/x86_64/stdlib/baseline-asserts +++ b/test/abi/Inputs/macOS/x86_64/stdlib/baseline-asserts @@ -6836,6 +6836,7 @@ _$ss16TextOutputStreamPsE11_writeASCIIyySRys5UInt8VGF _$ss16TextOutputStreamPsE5_lockyyF _$ss16TextOutputStreamPsE7_unlockyyF _$ss16TextOutputStreamTL +_$ss16_DebuggerSupportO20stringForPrintObject_15mangledTypeNameSb_SStSVSg_SStFZ _$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ _$ss16_DebuggerSupportOMa _$ss16_DebuggerSupportOMn From 4504063bf456599f1c303cbc8b2124d0037f5709 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Wed, 12 Nov 2025 09:21:35 -0800 Subject: [PATCH 08/17] Remove uses of unsafe unwrap in tests --- test/stdlib/DebuggerSupport.swift | 33 ++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/test/stdlib/DebuggerSupport.swift b/test/stdlib/DebuggerSupport.swift index f80f5c1cc5d50..81633d7818b14 100644 --- a/test/stdlib/DebuggerSupport.swift +++ b/test/stdlib/DebuggerSupport.swift @@ -115,9 +115,12 @@ if #available(SwiftStdlib 6.1, *) { @available(SwiftStdlib 6.3, *) func _expectStringForPrintObject(_ pointer: UnsafePointer, output: String) { - let mangledTypeName = _mangledTypeName(T.self) + guard let mangledTypeName = _mangledTypeName(T.self) else { + expectTrue(false) + return + } let (success, printed) = - _DebuggerSupport.stringForPrintObject(UnsafeRawPointer(pointer), mangledTypeName: mangledTypeName!) + _DebuggerSupport.stringForPrintObject(UnsafeRawPointer(pointer), mangledTypeName: mangledTypeName) expectTrue(success) expectEqual(printed, output) } @@ -136,22 +139,28 @@ if #available(SwiftStdlib 6.3, *) { do { var val3 = StructIsNonCopyable() - withUnsafeBytes(of: &val3) { bytes in - let mangledTypeName = _mangledTypeName(StructIsNonCopyable.self) - let (success, printed) = - _DebuggerSupport.stringForPrintObject(bytes.baseAddress!, mangledTypeName: mangledTypeName!) - expectFalse(success) - expectEqual(printed, "type not found for mangled name: \(mangledTypeName!)") + if let mangledTypeName = _mangledTypeName(StructIsNonCopyable.self) { + withUnsafeBytes(of: &val3) { bytes in + let (success, printed) = + _DebuggerSupport.stringForPrintObject(bytes.baseAddress!, mangledTypeName: mangledTypeName) + expectFalse(success) + expectEqual(printed, "type not found for mangled name: \(mangledTypeName)") + } + } else { + expectTrue(false) } } do { let obj = ClassWithMembers() let pointer = unsafeBitCast(obj, to: UnsafeRawPointer.self) - let mangledTypeName = _mangledTypeName(ClassWithMembers.self) - let (success, printed) = _DebuggerSupport.stringForPrintObject(pointer, mangledTypeName: mangledTypeName!) - expectTrue(success) - expectEqual(printed.hasPrefix(" Date: Wed, 12 Nov 2025 11:06:18 -0800 Subject: [PATCH 09/17] Remove last use of unsafe unwrap in tests --- test/stdlib/DebuggerSupport.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/stdlib/DebuggerSupport.swift b/test/stdlib/DebuggerSupport.swift index 81633d7818b14..46ded27eb1977 100644 --- a/test/stdlib/DebuggerSupport.swift +++ b/test/stdlib/DebuggerSupport.swift @@ -141,8 +141,12 @@ if #available(SwiftStdlib 6.3, *) { var val3 = StructIsNonCopyable() if let mangledTypeName = _mangledTypeName(StructIsNonCopyable.self) { withUnsafeBytes(of: &val3) { bytes in + guard let pointer = bytes.baseAddress else { + expectTrue(false) + return + } let (success, printed) = - _DebuggerSupport.stringForPrintObject(bytes.baseAddress!, mangledTypeName: mangledTypeName) + _DebuggerSupport.stringForPrintObject(pointer, mangledTypeName: mangledTypeName) expectFalse(success) expectEqual(printed, "type not found for mangled name: \(mangledTypeName)") } From 92a23dd0d1ce3f2fc741f00424210f3855f308f6 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Wed, 12 Nov 2025 15:08:41 -0800 Subject: [PATCH 10/17] Disable one test case --- test/stdlib/DebuggerSupport.swift | 34 +++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/test/stdlib/DebuggerSupport.swift b/test/stdlib/DebuggerSupport.swift index 46ded27eb1977..d64b05db1618e 100644 --- a/test/stdlib/DebuggerSupport.swift +++ b/test/stdlib/DebuggerSupport.swift @@ -137,23 +137,23 @@ if #available(SwiftStdlib 6.3, *) { _expectStringForPrintObject(&val2, output: "▿ Optional\n ▿ some : StructWithMembers\n - a : 1\n - b : \"Hello World\"\n") - do { - var val3 = StructIsNonCopyable() - if let mangledTypeName = _mangledTypeName(StructIsNonCopyable.self) { - withUnsafeBytes(of: &val3) { bytes in - guard let pointer = bytes.baseAddress else { - expectTrue(false) - return - } - let (success, printed) = - _DebuggerSupport.stringForPrintObject(pointer, mangledTypeName: mangledTypeName) - expectFalse(success) - expectEqual(printed, "type not found for mangled name: \(mangledTypeName)") - } - } else { - expectTrue(false) - } - } + // do { + // var val3 = StructIsNonCopyable() + // if let mangledTypeName = _mangledTypeName(StructIsNonCopyable.self) { + // withUnsafeBytes(of: &val3) { bytes in + // guard let pointer = bytes.baseAddress else { + // expectTrue(false) + // return + // } + // let (success, printed) = + // _DebuggerSupport.stringForPrintObject(pointer, mangledTypeName: mangledTypeName) + // expectFalse(success) + // expectEqual(printed, "type not found for mangled name: \(mangledTypeName)") + // } + // } else { + // expectTrue(false) + // } + // } do { let obj = ClassWithMembers() From 2b68a5800ecc2f13941b2925ba641f95be00b33e Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Wed, 12 Nov 2025 16:05:18 -0800 Subject: [PATCH 11/17] Update means of getting object pointer --- test/stdlib/DebuggerSupport.swift | 36 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/test/stdlib/DebuggerSupport.swift b/test/stdlib/DebuggerSupport.swift index d64b05db1618e..93314f28bb5f6 100644 --- a/test/stdlib/DebuggerSupport.swift +++ b/test/stdlib/DebuggerSupport.swift @@ -137,27 +137,27 @@ if #available(SwiftStdlib 6.3, *) { _expectStringForPrintObject(&val2, output: "▿ Optional\n ▿ some : StructWithMembers\n - a : 1\n - b : \"Hello World\"\n") - // do { - // var val3 = StructIsNonCopyable() - // if let mangledTypeName = _mangledTypeName(StructIsNonCopyable.self) { - // withUnsafeBytes(of: &val3) { bytes in - // guard let pointer = bytes.baseAddress else { - // expectTrue(false) - // return - // } - // let (success, printed) = - // _DebuggerSupport.stringForPrintObject(pointer, mangledTypeName: mangledTypeName) - // expectFalse(success) - // expectEqual(printed, "type not found for mangled name: \(mangledTypeName)") - // } - // } else { - // expectTrue(false) - // } - // } + do { + var val3 = StructIsNonCopyable() + if let mangledTypeName = _mangledTypeName(StructIsNonCopyable.self) { + withUnsafeBytes(of: &val3) { bytes in + guard let pointer = bytes.baseAddress else { + expectTrue(false) + return + } + let (success, printed) = + _DebuggerSupport.stringForPrintObject(pointer, mangledTypeName: mangledTypeName) + expectFalse(success) + expectEqual(printed, "type not found for mangled name: \(mangledTypeName)") + } + } else { + expectTrue(false) + } + } do { let obj = ClassWithMembers() - let pointer = unsafeBitCast(obj, to: UnsafeRawPointer.self) + let pointer = Unmanaged.passUnretained(obj).toOpaque() if let mangledTypeName = _mangledTypeName(ClassWithMembers.self) { let (success, printed) = _DebuggerSupport.stringForPrintObject(pointer, mangledTypeName: mangledTypeName) expectTrue(success) From 2263a34a96e57ccb42261d093aafa1b4bb45c104 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Wed, 12 Nov 2025 17:36:27 -0800 Subject: [PATCH 12/17] Build the test with debug info --- test/stdlib/DebuggerSupport.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/stdlib/DebuggerSupport.swift b/test/stdlib/DebuggerSupport.swift index 93314f28bb5f6..93a7fe0c20f89 100644 --- a/test/stdlib/DebuggerSupport.swift +++ b/test/stdlib/DebuggerSupport.swift @@ -1,4 +1,4 @@ -// RUN: %target-run-simple-swift +// RUN: %target-run-simple-swift(-g -Onone) // REQUIRES: executable_test // REQUIRES: optimized_stdlib // REQUIRES: reflection From c7f97ba8e669f03c4197dd6f47f4542bac359433 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Thu, 13 Nov 2025 11:33:30 -0800 Subject: [PATCH 13/17] Manually retain object to control lifetime --- test/stdlib/DebuggerSupport.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/stdlib/DebuggerSupport.swift b/test/stdlib/DebuggerSupport.swift index 93a7fe0c20f89..5b98b5852badb 100644 --- a/test/stdlib/DebuggerSupport.swift +++ b/test/stdlib/DebuggerSupport.swift @@ -1,4 +1,4 @@ -// RUN: %target-run-simple-swift(-g -Onone) +// RUN: %target-run-simple-swift // REQUIRES: executable_test // REQUIRES: optimized_stdlib // REQUIRES: reflection @@ -157,7 +157,8 @@ if #available(SwiftStdlib 6.3, *) { do { let obj = ClassWithMembers() - let pointer = Unmanaged.passUnretained(obj).toOpaque() + let retained = Unmanaged.passRetained(obj) + let pointer = retained.toOpaque() if let mangledTypeName = _mangledTypeName(ClassWithMembers.self) { let (success, printed) = _DebuggerSupport.stringForPrintObject(pointer, mangledTypeName: mangledTypeName) expectTrue(success) @@ -165,6 +166,7 @@ if #available(SwiftStdlib 6.3, *) { } else { expectTrue(false) } + retained.release() } } } From 8200910bd5d2e0f8c103b65aa1f1e8c63ee13cb8 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Thu, 13 Nov 2025 15:18:38 -0800 Subject: [PATCH 14/17] Treat object pointers different from non-object values --- stdlib/public/core/DebuggerSupport.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/stdlib/public/core/DebuggerSupport.swift b/stdlib/public/core/DebuggerSupport.swift index 7a93ad5a3057b..96a7ba18ee1ed 100644 --- a/stdlib/public/core/DebuggerSupport.swift +++ b/stdlib/public/core/DebuggerSupport.swift @@ -350,7 +350,11 @@ public enum _DebuggerSupport { } func loadPointer(type: T.Type) -> Any { - unsafe pointer.load(as: T.self) + if type is AnyObject.Type { + unsafe pointer.assumingMemoryBound(to: T.self).pointee + } else { + unsafe pointer.load(as: T.self) + } } let anyValue = _openExistential(type, do: loadPointer) return (true, stringForPrintObject(anyValue)) From 506fc9f942eab1bed2f129b6acc830d894773d5c Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Thu, 13 Nov 2025 13:19:15 -0800 Subject: [PATCH 15/17] Replace passRetained+release with withExtendedLifetime --- test/stdlib/DebuggerSupport.swift | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/stdlib/DebuggerSupport.swift b/test/stdlib/DebuggerSupport.swift index 5b98b5852badb..0791034f656cd 100644 --- a/test/stdlib/DebuggerSupport.swift +++ b/test/stdlib/DebuggerSupport.swift @@ -157,16 +157,16 @@ if #available(SwiftStdlib 6.3, *) { do { let obj = ClassWithMembers() - let retained = Unmanaged.passRetained(obj) - let pointer = retained.toOpaque() if let mangledTypeName = _mangledTypeName(ClassWithMembers.self) { - let (success, printed) = _DebuggerSupport.stringForPrintObject(pointer, mangledTypeName: mangledTypeName) - expectTrue(success) - expectEqual(printed.hasPrefix(" Date: Fri, 14 Nov 2025 16:13:36 -0800 Subject: [PATCH 16/17] Fix point to object cast, and fix test assert --- stdlib/public/core/DebuggerSupport.swift | 3 ++- test/stdlib/DebuggerSupport.swift | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/stdlib/public/core/DebuggerSupport.swift b/stdlib/public/core/DebuggerSupport.swift index 96a7ba18ee1ed..461ecee03875a 100644 --- a/stdlib/public/core/DebuggerSupport.swift +++ b/stdlib/public/core/DebuggerSupport.swift @@ -351,11 +351,12 @@ public enum _DebuggerSupport { func loadPointer(type: T.Type) -> Any { if type is AnyObject.Type { - unsafe pointer.assumingMemoryBound(to: T.self).pointee + unsafe unsafeBitCast(pointer, to: AnyObject.self) } else { unsafe pointer.load(as: T.self) } } + let anyValue = _openExistential(type, do: loadPointer) return (true, stringForPrintObject(anyValue)) } diff --git a/test/stdlib/DebuggerSupport.swift b/test/stdlib/DebuggerSupport.swift index 0791034f656cd..999af04b77eeb 100644 --- a/test/stdlib/DebuggerSupport.swift +++ b/test/stdlib/DebuggerSupport.swift @@ -162,7 +162,7 @@ if #available(SwiftStdlib 6.3, *) { let pointer = unsafeBitCast(obj, to: UnsafeRawPointer.self) let (success, printed) = _DebuggerSupport.stringForPrintObject(pointer, mangledTypeName: mangledTypeName) expectTrue(success) - expectEqual(printed.hasPrefix(" Date: Sat, 15 Nov 2025 09:20:08 -0800 Subject: [PATCH 17/17] Cast objects to their type T instead of AnyObject --- stdlib/public/core/DebuggerSupport.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/public/core/DebuggerSupport.swift b/stdlib/public/core/DebuggerSupport.swift index 461ecee03875a..0eba1258947a7 100644 --- a/stdlib/public/core/DebuggerSupport.swift +++ b/stdlib/public/core/DebuggerSupport.swift @@ -351,7 +351,7 @@ public enum _DebuggerSupport { func loadPointer(type: T.Type) -> Any { if type is AnyObject.Type { - unsafe unsafeBitCast(pointer, to: AnyObject.self) + unsafe unsafeBitCast(pointer, to: T.self) } else { unsafe pointer.load(as: T.self) }