mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Debug] Add pointer based stringForPrintObject (#84742)
Adds an overload of `_DebuggerSupport.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. rdar://158968103
This commit is contained in:
@@ -328,6 +328,38 @@ public enum _DebuggerSupport {
|
||||
|
||||
return target
|
||||
}
|
||||
|
||||
// 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<String>.
|
||||
@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(
|
||||
mangledTypeName,
|
||||
UInt(mangledTypeName.count),
|
||||
genericContext: nil,
|
||||
genericArguments: nil)
|
||||
else {
|
||||
return (false, "type not found for mangled name: \(mangledTypeName)")
|
||||
}
|
||||
|
||||
func loadPointer<T>(type: T.Type) -> Any {
|
||||
if type is AnyObject.Type {
|
||||
unsafe unsafeBitCast(pointer, to: T.self)
|
||||
} else {
|
||||
unsafe pointer.load(as: T.self)
|
||||
}
|
||||
}
|
||||
|
||||
let anyValue = _openExistential(type, do: loadPointer)
|
||||
return (true, stringForPrintObject(anyValue))
|
||||
}
|
||||
}
|
||||
|
||||
public func _stringForPrintObject(_ value: Any) -> String {
|
||||
|
||||
@@ -6815,6 +6815,7 @@ _$ss16TextOutputStreamPsE11_writeASCIIyySRys5UInt8VGF
|
||||
_$ss16TextOutputStreamPsE5_lockyyF
|
||||
_$ss16TextOutputStreamPsE7_unlockyyF
|
||||
_$ss16TextOutputStreamTL
|
||||
_$ss16_DebuggerSupportO20stringForPrintObject_15mangledTypeNameSb_SStSVSg_SStFZ
|
||||
_$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
|
||||
_$ss16_DebuggerSupportOMa
|
||||
_$ss16_DebuggerSupportOMn
|
||||
|
||||
@@ -6815,6 +6815,7 @@ _$ss16TextOutputStreamPsE11_writeASCIIyySRys5UInt8VGF
|
||||
_$ss16TextOutputStreamPsE5_lockyyF
|
||||
_$ss16TextOutputStreamPsE7_unlockyyF
|
||||
_$ss16TextOutputStreamTL
|
||||
_$ss16_DebuggerSupportO20stringForPrintObject_15mangledTypeNameSb_SStSVSg_SStFZ
|
||||
_$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
|
||||
_$ss16_DebuggerSupportOMa
|
||||
_$ss16_DebuggerSupportOMn
|
||||
|
||||
@@ -6836,6 +6836,7 @@ _$ss16TextOutputStreamPsE11_writeASCIIyySRys5UInt8VGF
|
||||
_$ss16TextOutputStreamPsE5_lockyyF
|
||||
_$ss16TextOutputStreamPsE7_unlockyyF
|
||||
_$ss16TextOutputStreamTL
|
||||
_$ss16_DebuggerSupportO20stringForPrintObject_15mangledTypeNameSb_SStSVSg_SStFZ
|
||||
_$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
|
||||
_$ss16_DebuggerSupportOMa
|
||||
_$ss16_DebuggerSupportOMn
|
||||
|
||||
@@ -6836,6 +6836,7 @@ _$ss16TextOutputStreamPsE11_writeASCIIyySRys5UInt8VGF
|
||||
_$ss16TextOutputStreamPsE5_lockyyF
|
||||
_$ss16TextOutputStreamPsE7_unlockyyF
|
||||
_$ss16TextOutputStreamTL
|
||||
_$ss16_DebuggerSupportO20stringForPrintObject_15mangledTypeNameSb_SStSVSg_SStFZ
|
||||
_$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
|
||||
_$ss16_DebuggerSupportOMa
|
||||
_$ss16_DebuggerSupportOMn
|
||||
|
||||
@@ -10,6 +10,11 @@ struct StructWithMembers {
|
||||
var b = "Hello World"
|
||||
}
|
||||
|
||||
struct StructIsNonCopyable: ~Copyable {
|
||||
var a = 1
|
||||
var b = "Hello World"
|
||||
}
|
||||
|
||||
class ClassWithMembers {
|
||||
var a = 1
|
||||
var b = "Hello World"
|
||||
@@ -108,6 +113,64 @@ if #available(SwiftStdlib 6.1, *) {
|
||||
}
|
||||
}
|
||||
|
||||
@available(SwiftStdlib 6.3, *)
|
||||
func _expectStringForPrintObject<T>(_ pointer: UnsafePointer<T>, output: String) {
|
||||
guard let mangledTypeName = _mangledTypeName(T.self) else {
|
||||
expectTrue(false)
|
||||
return
|
||||
}
|
||||
let (success, printed) =
|
||||
_DebuggerSupport.stringForPrintObject(UnsafeRawPointer(pointer), mangledTypeName: mangledTypeName)
|
||||
expectTrue(success)
|
||||
expectEqual(printed, output)
|
||||
}
|
||||
|
||||
if #available(SwiftStdlib 6.3, *) {
|
||||
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: StructWithMembers? = StructWithMembers()
|
||||
_expectStringForPrintObject(&val2,
|
||||
output: "▿ Optional<StructWithMembers>\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 {
|
||||
let obj = ClassWithMembers()
|
||||
if let mangledTypeName = _mangledTypeName(ClassWithMembers.self) {
|
||||
withExtendedLifetime(obj) { obj in
|
||||
let pointer = unsafeBitCast(obj, to: UnsafeRawPointer.self)
|
||||
let (success, printed) = _DebuggerSupport.stringForPrintObject(pointer, mangledTypeName: mangledTypeName)
|
||||
expectTrue(success)
|
||||
expectTrue(printed.hasPrefix("<ClassWithMembers: 0x"))
|
||||
}
|
||||
} else {
|
||||
expectTrue(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RefCountedObj {
|
||||
var patatino : Int
|
||||
init(_ p : Int) {
|
||||
|
||||
Reference in New Issue
Block a user