【问题标题】:Swift crash in swift_getSingletonMetadata, "type metadata accessor"swift_getSingletonMetadata 中的 Swift 崩溃,“类型元数据访问器”
【发布时间】:2020-05-30 03:39:18
【问题描述】:

我从我的 Mac 应用程序中收到了一些奇怪的崩溃日志。这是崩溃的线程:

OS Version:      Mac OS X 10.14.6 (18G103)
Report Version:  104

Exception Type:  SIGSEGV
Exception Codes: SEGV_MAPERR at 0x0
Crashed Thread:  8

Thread 8 Crashed:
0   ???                                  0x0000000000000000 0x0 + 0
1   libswiftCore.dylib                   0x00007fff79a743f3 swift_getSingletonMetadata + 578
2   PowerPhotos                          0x000000010323f30d type metadata accessor for PowerPhotos.IPAssetCollectionUpdate (<compiler-generated>:0)
3   libswiftCore.dylib                   0x00007fff79a8c94c swift::TargetProtocolConformanceDescriptor<swift::InProcess>::getCanonicalTypeMetadata() const + 171
4   libswiftCore.dylib                   0x00007fff79a8da24 swift_conformsToSwiftProtocolImpl(swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolDescriptor<swift::InProcess> const*, llvm::StringRef) + 291
5   libswiftCore.dylib                   0x00007fff79a8d884 swift_conformsToProtocolImpl(swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolDescriptor<swift::InProcess> const*) + 99
6   PowerPhotos                          0x000000010339e7a9 swift::swift50override_conformsToProtocol(swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolDescriptor<swift::InProcess> const*, swift::TargetWitnessTable<swift::InProcess> const* (*)(swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolDescriptor<swift::InProcess> const*)) + 56
7   libswiftCore.dylib                   0x00007fff79a6215a swift::_conformsToProtocol(swift::OpaqueValue const*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolDescriptorRef<swift::InProcess>, swift::TargetWitnessTable<swift::InProcess> const**) + 41
8   libswiftCore.dylib                   0x00007fff79a65f97 _conformsToProtocols(swift::OpaqueValue const*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetExistentialTypeMetadata<swift::InProcess> const*, swift::TargetWitnessTable<swift::InProcess> const**) + 230
9   libswiftCore.dylib                   0x00007fff79a65369 _dynamicCastToExistential(swift::OpaqueValue*, swift::OpaqueValue*, swift::TargetMetadata<swift::InProcess> const*, swift::TargetExistentialTypeMetadata<swift::InProcess> const*, swift::DynamicCastFlags) + 488
10  libswiftCore.dylib                   0x00007fff79836517 Swift._print_unlocked<A, B where B: Swift.TextOutputStream>(A, inout B) -> () + 550
11  PowerPhotos                          0x00000001031e2483 PowerPhotos.IPArchiveUpdateOperation.(loadFromReplay in _C3BCBD43848FA0F2A85DA8591115A6A7)() -> PowerPhotos.IPArchiveLoadResult (<compiler-generated>:0)
12  PowerPhotos                          0x00000001031e1700 PowerPhotos.IPArchiveUpdateOperation.(loadFromPreferredDatabase in _C3BCBD43848FA0F2A85DA8591115A6A7)() -> (PowerPhotos.IPArchiveLoadResult, Swift.Error?) (IPArchiveUpdateOperation.swift:430)
13  PowerPhotos                          0x00000001031e08fa PowerPhotos.IPArchiveUpdateOperation.perform() throws -> Any (IPArchiveUpdateOperation.swift:218)
14  PowerPhotos                          0x00000001031e179c @objc PowerPhotos.IPArchiveUpdateOperation.perform() throws -> Any (<compiler-generated>:0)
15  BWFoundation                         0x00000001036c8173 -[BWOperation main] (BWOperation.m:124)
16  PowerPhotosKit                       0x0000000103898e71 -[IPOperation main] (IPOperation.m:287)
17  Foundation                           0x00007fff502f5ced -[__NSOperationInternal _start:] + 684
18  Foundation                           0x00007fff5031fca7 __NSOQSchedule_f + 226
19  libdispatch.dylib                    0x00007fff7a0055f8 _dispatch_call_block_and_release + 11
20  libdispatch.dylib                    0x00007fff7a00663d _dispatch_client_callout + 7
21  libdispatch.dylib                    0x00007fff7a008de6 _dispatch_continuation_pop + 413
22  libdispatch.dylib                    0x00007fff7a0084a3 _dispatch_async_redirect_invoke + 702
23  libdispatch.dylib                    0x00007fff7a0143bc _dispatch_root_queue_drain + 323
24  libdispatch.dylib                    0x00007fff7a014b46 _dispatch_worker_thread2 + 89
25  libsystem_pthread.dylib              0x00007fff7a2466b3 _pthread_wqthread + 582
26  libsystem_pthread.dylib              0x00007fff7a2463fd start_wqthread + 12
27  ???                                  0x0000000054485244 0x0 + 0

第 11 帧是最后一次看到我自己的代码,那行代码如下所示:

return IPArchiveLoadResult(error: NSError(description: "Replay did not complete \(replayDatabase.replayState.debugDescription)"))

所以看起来对 debugDescription 的调用正在生成堆栈跟踪的其余部分,以创建该插值字符串。这最终在第 3 帧中结束,该帧引用了“PowerPhotos.IPAssetCollectionUpdate 的类型元数据访问器”。

但奇怪的是:IPAssetCollectionUpdate 与调用这些东西的代码完全无关。它位于应用程序的完全不同的部分。所以我认为这触发了 Swift 在这里执行的任何元数据加载,这主要是巧合。

查看 IAssetCollectionUpdate,我想我明白了可能是什么原因造成的:

@available(OSX 10.15, *)
struct IPAssetCollectionUpdate {
    let assetCollection: PHAssetCollection
    let diff: CollectionDifference<PHAsset>
}

请注意,IPAssetCollectionUpdate 被标记为仅在 macOS 10.15 上可用,并且崩溃都发生在 macOS 10.14 上。 PHAssetCollection 和 PHAsset 在 macOS 10.14 上确实存在,但 CollectionDifference 不存在。这在应用程序的其余部分不是问题,因为所有内容都受 @available 指令保护,但似乎 Swift 运行时仍在尝试挖掘此结构并生成一些内部元数据并在它不能时爆炸处理 CollectionDifference。或者类似的东西?

无论如何,这就是设置,所以我的问题是:

  1. 这应该被认为是一个 Swift 错误吗?似乎所有内容都正确注释了可用性指令,我应该能够在 macOS 10.14 上发布它并且不会发生崩溃,因为我在 10.14 上根本没有真正使用过这个结构。
  2. 不管是谁的错,有什么办法可以更改此代码,使其不会在 10.14 上崩溃?我能想到的最好的办法是将它分解为我的应用程序中的可加载包,并在 10.15 上运行时手动加载包。不过,对于这个愚蠢的问题,这似乎需要做很多工作,我想知道是否有其他更简单的方法来处理这个问题。

我正在使用 Xcode 11.5 和 Swift 5 进行编译。

【问题讨论】:

    标签: ios swift xcode macos


    【解决方案1】:

    好的,Stack Overflow 在这里对我来说是一个很好的橡皮鸭,我可以通过执行以下操作来避免崩溃:

    struct IPAssetCollectionUpdate {
        let assetCollection: PHAssetCollection
        let typeErasedDiff: Any
    
        var diff: CollectionDifference<PHAsset> {
            return self.typeErasedDiff as! CollectionDifference<PHAsset>
        }
    }
    

    这很糟糕,但它确实有效。但是我关于这是否应该被视为 Swift 错误的问题仍然存在,以及是否有更受认可的方式来编写这种类型的代码。

    【讨论】:

      猜你喜欢
      • 2020-03-11
      • 2022-01-12
      • 2016-06-14
      • 1970-01-01
      • 2021-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多