Swift Runtime中EXC_BAD_ACCESS错误排查及相关问题咨询
问题:Swift/ObjC与C++交互时异步API调用出现EXC_BAD_ACCESS错误
我主要从事C开发,刚接触Swift/ObjC技术栈。项目以跨平台C实现为主,包含MacOS专属的Swift/ObjC组件。在调用异步API创建FactoryProduct对象时出现EXC_BAD_ACCESS错误,相关代码及回溯信息如下:
Swift代码
@objc public class SomeFactory: NSObject { @objc public func GetInstance(appTitle: String, iconImage: NSImage?, transactionId: UUID, resourceId: String, completionHandler: @escaping (FactoryProduct?) -> ()) { Task { guard let product = try? await FactoryProduct(appTitle: appTitle, iconImage: iconImage, transactionId: transactionId, resourceId: resourceId) else { completionHandler(nil) return } completionHandler(product) } } }
Objective-C++ (.mm) 调用代码
static std::optional<FactoryProduct * __nonnull> GetFactoryProduct(std::string const &resourceTitle, std::string const &iconDataEncoded, std::string const &transactionId, std::string const &resourceId) { /* ...snip... makes the NSImage * */ __block FactoryProduct *product = nil; __block std::promise<void> blockSignal; auto signalFuture = blockSignal.get_future(); [[[SomeFactory alloc] init] GetInstanceWithAppTitle:[NSString stringWithUTF8String:resourceTitle.c_str()] iconImage:iconImage transactionId:[[NSUUID alloc] initWithUUIDString:[NSString stringWithUTF8String:transactionId.c_str()]] resourceId:[NSString stringWithUTF8String:resourceId.c_str()] completionHandler:^(FactoryProduct *_Nullable instantiatedObject) { if(instantiatedObject != nil) { product = instantiatedObject; } blockSignal.set_value(); }]; signalFuture.wait(); if(product != nil) { return product; } return {}; }
回溯信息(Xcode 13.2.1/13.4,macOS 12.6 Intel)
* thread #17, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) * frame #0: 0x00007ff811a96ee7 libswiftCore.dylib`swift::ResolveAsSymbolicReference::operator()(swift::Demangle::__runtime::SymbolicReferenceKind, swift::Demangle::__runtime::Directness, int, void const*) + 55 frame #1: 0x00007ff811abbe7d libswiftCore.dylib`swift::Demangle::__runtime::Demangler::demangleSymbolicReference(unsigned char) + 141 frame #2: 0x00007ff811ab8bb8 libswiftCore.dylib`swift::Demangle::__runtime::Demangler::demangleType(__swift::__runtime::llvm::StringRef, std::__1::function<swift::Demangle::__runtime::Node* (swift::Demangle::__runtime::SymbolicReferenceKind, swift::Demangle::__runtime::Directness, int, void const*)>) + 168 frame #3: 0x00007ff811a9c583 libswiftCore.dylib`swift_getTypeByMangledNameImpl(swift::MetadataRequest, __swift::__runtime::llvm::StringRef, void const* const*, std::__1::function<swift::TargetMetadata<swift::InProcess> const* (unsigned int, unsigned int)>, std::__1::function<swift::TargetWitnessTable<swift::InProcess> const* (swift::TargetMetadata<swift::InProcess> const*, unsigned int)>) + 483 frame #4: 0x00007ff811a99cbd libswiftCore.dylib`swift_getTypeByMangledName + 477 frame #5: 0x00007ff811a99eeb libswiftCore.dylib`swift_getTypeByMangledNameInContext + 171 frame #6: 0x0000000101f6e429 myApp`__swift_instantiateConcreteTypeFromMangledName + 89 frame #7: 0x0000000101f6f679 myApp`myAppStaticLib.SomeFactory.GetInstance(appTitle: Swift.String, iconImage: Swift.Optional<__C.NSImage>, transactionId: Foundation.UUID, resourceId: Swift.String, completionHandler: (Swift.Optional<myAppStaticLib.FactoryProduct>) -> ()) -> () + 409 ...
项目中myApp依赖myAppStaticLib静态库,我有两个疑问:
- 这是Xcode 13.x中的已知问题吗?
- 栈帧#6中从
myAppStaticLib切换到myApp的上下文是否存在问题,还是属于正常现象?
已尝试的无效方案
修改SomeFactory.GetInstance实现,采用Swift 5.5异步ObjC交互方案,代码如下:
@objc public class SomeFactory: NSObject { @objc public func GetInstance(appTitle: String, iconImage: NSImage?, transactionId: String, resourceId: String) async -> FactoryProduct? { /* ...snip... make product */ return product } }
寻求改进建议
希望得到针对当前实现的优化方案,解决EXC_BAD_ACCESS错误。
内容的提问来源于stack exchange,提问作者Naman Arora
相关产品推荐
相关产品推荐

