wickwirew / Runtime

A Swift Runtime library for viewing type info, and the dynamic getting and setting of properties.
MIT License
1.08k stars 94 forks source link

The mangledName property of TypeInfo has incorrect or missing results #65

Open benpious opened 4 years ago

benpious commented 4 years ago

I would expect the following code to print something like $s11TestRuntime0A8ManglingCMn. However, the actual output is simply TestMangling.

import Runtime

class TestMangling {

}

let type = try! typeInfo(of: TestMangling.self)
print(type.mangledName)

For a few types I've tried, the output is an empty string. I'm guessing that the layout of the nominal type descriptor has changed since Runtime was first written, but I'm not sure how to verify this as I'm not sure where the struct for nominal type descriptors actually lives in the swift runtime source.

I'm using Runtime 2.1.1, Swift 5.1.

wickwirew commented 4 years ago

Yea unfortunately it looks the like the type descriptor's only have the name now and not the mangled name.

benpious commented 4 years ago

Thanks for responding. In the runtime source code like the variable name is indeed just "name" now.

I did find a potential solution to this issue: use dladdr on a Any.Type pointer and you get a mangled name from dli_sname. This might not work for all types, and I don't know if it would make sense to add to this library, but it is an option.

For the benefit of anyone who stumbles onto this issue and is interested in how to do this, here's a code snippet:

import Darwin

func mangledName(for type: Any.Type) -> String {
   let pointer = UnsafeRawPointer(bitPattern: unsafeBitCast(type, to: Int.self))
   var info = Dl_info()
   dladdr(pointer, &info)
   return String(cString: info.dli_sname)
}
rogerluan commented 3 years ago

@benpious that code errors out during runtime for me 😞

Fatal error: Can't unsafeBitCast between types of different sizes: file /Library/Caches/com.apple.xbs/Binaries/SwiftPrebuiltSDKModules_macOS/install/TempContent/Objects/EmbeddedProjects/CrossTrain_macOS_SDK/macOS_SDK/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib/swift/Swift.swiftmodule/x86_64.swiftinterface, line 2910

Passing in a simple struct as the type to be analyzed. Did you face this and could resolve? 🙏