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

Crash in `typeInfo(of:)` for enum bridged from Objective-C #69

Closed ole closed 4 years ago

ole commented 4 years ago

@wickwirew Thanks a lot for adding #68 so quickly!

This code crashes with EXC_BAD_ACCESS (code=1, address=0x0) after merging #68:

import Foundation
import Runtime

let bridgedEnum = try typeInfo(of: ComparisonResult.self)

Environment: macOS 10.15.4, Swift 5.2 (Xcode 11.4).

I'm not sure if inspecting an enum bridged from C/Objective-C is supposed to work at all. Regardless, it should probably not cause a crash.

The crash occurs in EnumMetadata.cases() in the call to record.pointee.type(genericContext:genericArguments:):

            ...
            return Case(
                name: record.pointee.fieldName(),
                payloadType: record.pointee._mangledTypeName.offset == 0
                    ? nil
                    : record.pointee.type( // Crashes here
                        genericContext: pointer.pointee.typeDescriptor,
                        genericArguments: genericVector
                    )
            )

Inside FieldRecord.type(genericContext:genericArguments:), the crash occurs in swift_getTypeByMangledNameInContext.

wickwirew commented 4 years ago

Unfortunately appears that the metadata does not contain the cases for objc enums, so it will have to skip it.

Fixed it in https://github.com/wickwirew/Runtime/pull/70 . Ended up adding two new properties so we can at least inspect the number of cases and cases with payloads when they are not available.

ole commented 4 years ago

Thanks a lot for the quick fix! I tried it out and confirm that the crash is fixed.

Unfortunately appears that the metadata does not contain the cases for objc enums, so it will have to skip it.

Nevertheless this is very useful. Since bridged enums will never have payload cases, having the number of cases is already useful information. Sure, it would be nice if the metadata contained the case names and their integer values, but I don't think Swift/Clang generate that info.