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
|
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 {
|
public func _stringForPrintObject(_ value: Any) -> String {
|
||||||
|
|||||||
@@ -6815,6 +6815,7 @@ _$ss16TextOutputStreamPsE11_writeASCIIyySRys5UInt8VGF
|
|||||||
_$ss16TextOutputStreamPsE5_lockyyF
|
_$ss16TextOutputStreamPsE5_lockyyF
|
||||||
_$ss16TextOutputStreamPsE7_unlockyyF
|
_$ss16TextOutputStreamPsE7_unlockyyF
|
||||||
_$ss16TextOutputStreamTL
|
_$ss16TextOutputStreamTL
|
||||||
|
_$ss16_DebuggerSupportO20stringForPrintObject_15mangledTypeNameSb_SStSVSg_SStFZ
|
||||||
_$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
|
_$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
|
||||||
_$ss16_DebuggerSupportOMa
|
_$ss16_DebuggerSupportOMa
|
||||||
_$ss16_DebuggerSupportOMn
|
_$ss16_DebuggerSupportOMn
|
||||||
|
|||||||
@@ -6815,6 +6815,7 @@ _$ss16TextOutputStreamPsE11_writeASCIIyySRys5UInt8VGF
|
|||||||
_$ss16TextOutputStreamPsE5_lockyyF
|
_$ss16TextOutputStreamPsE5_lockyyF
|
||||||
_$ss16TextOutputStreamPsE7_unlockyyF
|
_$ss16TextOutputStreamPsE7_unlockyyF
|
||||||
_$ss16TextOutputStreamTL
|
_$ss16TextOutputStreamTL
|
||||||
|
_$ss16_DebuggerSupportO20stringForPrintObject_15mangledTypeNameSb_SStSVSg_SStFZ
|
||||||
_$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
|
_$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
|
||||||
_$ss16_DebuggerSupportOMa
|
_$ss16_DebuggerSupportOMa
|
||||||
_$ss16_DebuggerSupportOMn
|
_$ss16_DebuggerSupportOMn
|
||||||
|
|||||||
@@ -6836,6 +6836,7 @@ _$ss16TextOutputStreamPsE11_writeASCIIyySRys5UInt8VGF
|
|||||||
_$ss16TextOutputStreamPsE5_lockyyF
|
_$ss16TextOutputStreamPsE5_lockyyF
|
||||||
_$ss16TextOutputStreamPsE7_unlockyyF
|
_$ss16TextOutputStreamPsE7_unlockyyF
|
||||||
_$ss16TextOutputStreamTL
|
_$ss16TextOutputStreamTL
|
||||||
|
_$ss16_DebuggerSupportO20stringForPrintObject_15mangledTypeNameSb_SStSVSg_SStFZ
|
||||||
_$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
|
_$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
|
||||||
_$ss16_DebuggerSupportOMa
|
_$ss16_DebuggerSupportOMa
|
||||||
_$ss16_DebuggerSupportOMn
|
_$ss16_DebuggerSupportOMn
|
||||||
|
|||||||
@@ -6836,6 +6836,7 @@ _$ss16TextOutputStreamPsE11_writeASCIIyySRys5UInt8VGF
|
|||||||
_$ss16TextOutputStreamPsE5_lockyyF
|
_$ss16TextOutputStreamPsE5_lockyyF
|
||||||
_$ss16TextOutputStreamPsE7_unlockyyF
|
_$ss16TextOutputStreamPsE7_unlockyyF
|
||||||
_$ss16TextOutputStreamTL
|
_$ss16TextOutputStreamTL
|
||||||
|
_$ss16_DebuggerSupportO20stringForPrintObject_15mangledTypeNameSb_SStSVSg_SStFZ
|
||||||
_$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
|
_$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
|
||||||
_$ss16_DebuggerSupportOMa
|
_$ss16_DebuggerSupportOMa
|
||||||
_$ss16_DebuggerSupportOMn
|
_$ss16_DebuggerSupportOMn
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ struct StructWithMembers {
|
|||||||
var b = "Hello World"
|
var b = "Hello World"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct StructIsNonCopyable: ~Copyable {
|
||||||
|
var a = 1
|
||||||
|
var b = "Hello World"
|
||||||
|
}
|
||||||
|
|
||||||
class ClassWithMembers {
|
class ClassWithMembers {
|
||||||
var a = 1
|
var a = 1
|
||||||
var b = "Hello World"
|
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 {
|
class RefCountedObj {
|
||||||
var patatino : Int
|
var patatino : Int
|
||||||
init(_ p : Int) {
|
init(_ p : Int) {
|
||||||
|
|||||||
Reference in New Issue
Block a user