高德地图swift报错Segmentation fault: 11

745 阅读4分钟

报错

有一种BUG叫莫名其妙

有一种坚持叫注释调试

有一种原因叫原来如此

终于要进行适配swift和最低版本支持到iOS10,也使用上Bitcode,心里好舒坦了。在新增加的代码使用swift后出现了莫名其妙的bug,问了度娘也说不清楚啊,或者给了一些似是而非的答案,全部试过了还是没有解决。

报错

编写好代码后,一直在报错。

3.	While emitting IR SIL function "@$s10Dispatcher27HXRidingBikesViewControllerC03mapD0_9didSelectySo05MAMapD0CSg_So012MAAnnotationD0CSgtF".
 for 'mapView(_:didSelect:)' (at 这里是目录RidingBikesViewController.swift:453:5)
0  swift                    0x000000010dee34ea PrintStackTraceSignalHandler(void*) + 42
1  swift                    0x000000010dee2cc0 SignalHandler(int) + 352
2  libsystem_platform.dylib 0x00007fff6b83b5fd _sigtramp + 29
3  libsystem_platform.dylib 0x00007ffee6068130 _sigtramp + 2055392080
4  swift                    0x0000000109e19689 swift::irgen::RecordTypeInfo<(anonymous namespace)::LoadableStructTypeInfo, swift::irgen::LoadableTypeInfo, (anonymous namespace)::StructFieldInfo, true, true>::packIntoEnumPayload(swift::irgen::IRGenFunction&, swift::irgen::EnumPayload&, swift::irgen::Explosion&, unsigned int) const + 121
5  swift                    0x0000000109e19689 swift::irgen::RecordTypeInfo<(anonymous namespace)::LoadableStructTypeInfo, swift::irgen::LoadableTypeInfo, (anonymous namespace)::StructFieldInfo, true, true>::packIntoEnumPayload(swift::irgen::IRGenFunction&, swift::irgen::EnumPayload&, swift::irgen::Explosion&, unsigned int) const + 121
6  swift                    0x0000000109e19689 swift::irgen::RecordTypeInfo<(anonymous namespace)::LoadableStructTypeInfo, swift::irgen::LoadableTypeInfo, (anonymous namespace)::StructFieldInfo, true, true>::packIntoEnumPayload(swift::irgen::IRGenFunction&, swift::irgen::EnumPayload&, swift::irgen::Explosion&, unsigned int) const + 121
7  swift                    0x0000000109e19689 swift::irgen::RecordTypeInfo<(anonymous namespace)::LoadableStructTypeInfo, swift::irgen::LoadableTypeInfo, (anonymous namespace)::StructFieldInfo, true, true>::packIntoEnumPayload(swift::irgen::IRGenFunction&, swift::irgen::EnumPayload&, swift::irgen::Explosion&, unsigned int) const + 121
8  swift                    0x0000000109d31e99 (anonymous namespace)::SinglePayloadEnumImplStrategy::emitValueInjection(swift::irgen::IRGenFunction&, swift::EnumElementDecl*, swift::irgen::Explosion&, swift::irgen::Explosion&) const + 297
9  swift                    0x0000000109e76d1b swift::SILInstructionVisitor<(anonymous namespace)::IRGenSILFunction, void>::visit(swift::SILInstruction*) + 38795
10 swift                    0x0000000109e6a053 swift::irgen::IRGenModule::emitSILFunction(swift::SILFunction*) + 8835
11 swift                    0x0000000109d1d722 swift::irgen::IRGenerator::emitGlobalTopLevel() + 1410
12 swift                    0x0000000109e48649 performIRGeneration(swift::IRGenOptions&, swift::ModuleDecl*, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> >, llvm::StringRef, swift::PrimarySpecificPaths const&, llvm::LLVMContext&, swift::SourceFile*, llvm::GlobalVariable**) + 1097
13 swift                    0x0000000109c3fa5f performCompileStepsPostSILGen(swift::CompilerInstance&, swift::CompilerInvocation&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule> >, bool, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::PrimarySpecificPaths const&, bool, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 4255
14 swift                    0x0000000109c34eba swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 48426
15 swift                    0x0000000109bacb73 main + 1283
16 libdyld.dylib            0x00007fff6b642cc9 start + 1
error: Segmentation fault: 11 (in target 'Dispatcher' from project 'dispatch')

报错的位置指向了

func mapView(_ mapView: MAMapView!, didSelect view: MAAnnotationView!) 

这有什么错呢,下载了高德地图的实例后,发现也是一样的写法啊。 排查思路:

  1. Bitcode关闭 (失败)
  2. 删除整片代码 (编译通过,可以确认这块代码有问题)
  3. 配置项比对 (失败 与高德地图实例都保持一致)
  4. Valid Architectures修改 (当添加armv7时,编译失败,其他编译成功)
  5. 注解代码,找到问题所在的代码

解决

步步为营,层层排查后,已经确定问题是出现在armv7架构的支持上,代码是在

func mapView(_ mapView: MAMapView!, didSelect view: MAAnnotationView!) {
        let anno: MAAnnotation = view.annotation

        if !(anno.isKind(of: MAUserLocation.classForCoder())) {
            view.transform = CGAffineTransform.init(scaleX: 1.2, y: 1.2)
        }

        if self.selectedBikeNumber == anno.subtitle {
            return
        }

        self.selectedBikeNumber = anno.subtitle

        if anno.isKind(of: MAPointAnnotation.classForCoder()) {
            let bikeNo: String! = anno.subtitle ?? ""

            let model = self.findBicycleWithBikeNumer(bikeNumber: bikeNo)

            if nil == model {
                return
            }

            // 保存中心点位置
            let coordinate = mapView.centerCoordinate
            if nil == self.lastCenterCoordinate {
                self.lastCenterCoordinate = coordinate
            }

            // 单车详情
            self.bicycleNumberLabel.text = model?.bikeNumber

            self.bicycleInfoView.isHidden = false
        }
    }

中的

self.selectedBikeNumber = anno.subtitle

分析原因为anno.subtitle的类型为option类型String??,而private var selectedBikeNumber: String? 需要先解包后才能赋值。 解决方案就是:

self.selectedBikeNumber = anno.subtitle ?? ""

anno.subtitle 解包后再赋值,编译通过。

篇外

以为已经大功告成了,但是最后发现原来还有一个坑啊。


could not reparse object file in bitcode bundle: 'Invalid bitcode version (Producer: '1200.0.22.8.0_0' Reader: '1103.0.32.62_0')', using libLTO version 'LLVM version 11.0.3, (clang-1103.0.32.62)' for architecture armv7



could not reparse object file in bitcode bundle: 'Invalid bitcode version (Producer: '1200.0.22.8.0_0' Reader: '1103.0.32.62_0')', using libLTO version 'LLVM version 11.0.3, (clang-1103.0.32.62)' for architecture arm64


看字面的意思是bitcode的版本不是最新版本啊。 查看本地的版本


Apple clang version 11.0.3 (clang-1103.0.32.62) Target: x86_64-apple-darwin19.6.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin


也就是说我Xcode的本地的版本是1103版本,而需要1200版本来编译才能成功进行bitcode的编译。那么原因应该就是在依赖的第三方库中有使用了1200版本编译的,所以才导致必须需要使用最新版本。 大概率是为即将推出的iOS14准备的Xcode的beta版本来进行编译的。!_! 解决方法: 将第三方库版本回退。

// END swift的长征第一步