# 加载so库后App出现闪退如何解决

#### 问题现象

在NAPI项目中链接so后出现APP启动闪退，CMakeLists.txt去除对应so链接后，APP无闪退现象。

#### 背景知识

在NDK工程中使用预构建库时，可以选择使用.so动态库或者.a静态库。so文件是共享库（shared library）的一种格式，程序在运行时动态链接so库中的代码，而不是像.a静态库编译时静态链接。

#### 问题定位

1.  查看crash日志。
    
    如下图，本次闪退为cppcrash，说明so加载链接完成，但是在代码运行时出现错误，根据下图Reason反馈得知由于空指针访问导致的报错。
    
    若闪退并非cppcrash而是jscrash，如下图，则说明js在访问so或者so加载链接出现问题，需要进一步定位。
    
    ArkTS出错位置和so对外导出的头文件如下二图：
    
2.  解压HAP包，查看lib目录下是否存在对应的so文件。
    1.  在HAP文件后添加.rar扩展名，点击压缩文件打开。
        
    2.  查看libs\\arm64-v8a目录下是否存在对应的so文件，如果缺失so文件说明在编译链接过程中没有将so文件打包进HAP，需要定位具体原因。
        
3.  确认HAP中的so文件是真实的库文件。
    
    由于在不同平台中软链接格式不同，此处以Linux为例。在Linux平台进行交叉编译时，一些源码通过编译链接后会生成多个链接文件，如下图。libjpeg.so/libjpeg.so.62均为链接文件，占用空间很小，而实际的so文件则为libjpeg.so.62.4.0,如果只拷贝链接文件会导致无法链接到真正的so文件。
    
4.  确认so文件依赖so文件均已导入进HAP包中。
    
    通过readelf -d xxx.so命令可以读取so文件中依赖的so文件，以下图libavcodec.so为例。该so同时依赖了libswreasample.so\\libavutil.so\\libz.so\\libc.so，需要确保如上so均打包进入HAP中或者存在于HarmonyOS的系统库中。
    

#### 分析结论

应用打包缺少so动态库文件及其依赖的其他动态库或者错误的so文件均会导致应用在启动过程中闪退。

#### 修改建议

1.  修改C/C++源码。
    
    根据cppcrash反馈的报错原因和堆栈调用定位代码出错原因，修改C/C++源码。
    
2.  将需要的so放置于libs\\${OHOS\_ARCH}目录下。
    
    将so放置于libs\\${OHOS\_ARCH}目录下后，编译HAP时会自动将so打包进去。
    
3.  重新编译去除so库版本号，避免软链接文件造成干扰。
    
    修改源码的编译文件，去除版本号的相关定义，重新编译生成库文件。
    
4.  保障so链接完整性。
    
    通过readelf等工具排查清楚so依赖的其他库文件，将该so所有的依赖库文件均放置于libs\\${OHOS\_ARCH}目录下。