• Android so库中UnsatisfiedLinkError


    最近游戏联运商反馈了一个so库中方法找不到,该问题比较常见,记录下排查过程:

    报错日志:

    Tombstone maker: 'xCrash 3.0.0'
    Crash type: 'java'
    Start time: '2022-09-06T13:05:49.347+0800'
    Crash time: '2022-09-06T13:05:58.850+0800'
    App ID: 'com.xxx.meta'
    App version: '3.34.0.2'
    Rooted: 'No'
    API level: '29'
    OS version: '10'
    ABI list: 'armeabi-v7a,armeabi' //该手机cpu支持abi
    Manufacturer: 'HUAWEI'
    Brand: 'HUAWEI'
    Model: 'MAR-TL00'
    Build fingerprint: 'HUAWEI/MAR-TL00/HWMAR:10/HUAWEIMAR-TL00/10.0.0.161C01:user/release-keys'
    pid: 16152, tid: 17111, name: GLThread 4240  >>> com.xxxxx.meta <<< //报错线程和进程名
    java stacktrace: //详细报错信息
    java.lang.UnsatisfiedLinkError: No implementation found for void org.appplay.lib.AppPlayNatives.nativeOnIdle() (tried Java_org_appplay_lib_AppPlayNatives_nativeOnIdle and Java_org_appplay_lib_AppPlayNatives_nativeOnIdle__)
    	at org.appplay.lib.AppPlayNatives.nativeOnIdle(Native Method)
    	at org.appplay.lib.AppPlayRenderer.onDrawFrame(AppPlayRenderer.java:71)
    	at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1592)
    	at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1281)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    1.检查c++代码中是否有该函数

    	void JNICALL Java_org_appplay_lib_AppPlayNatives_nativeOnIdle(JNIEnv *env, jclass)
    	{
    		if(s_App)
    			s_App->onIdle();
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    因此,排除了c++层代码没实现可能性。

    2.检查so库中是否有该函数信息

    根据so对应的cpu类型,选择对应ndkobjump 工具。这里,报错设备是areambi 选择arm-linux-androideabi-4.9

    其次使用其-d 命令 查看未strip 的so库中方法信息,中执行以下语句,

    xxxx\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin\arm-linux-androideabi-objdump.exe -d xxxx\libAppPlayJNI.so>stacktrace.txt
    
    • 1

    执行完后,会生成带有函数信息的stacktrace.txt ,如下图所示:
    在这里插入图片描述

    在其中,检索nativeOnIdle关键字,找到有关信息。

    00cc6494 <Java_org_appplay_lib_AppPlayNatives_nativeOnIdle>:
      cc6494:	e59f0014 	ldr	r0, [pc, #20]	; cc64b0 <Java_org_appplay_lib_AppPlayNatives_nativeOnIdle+0x1c>
      cc6498:	e79f0000 	ldr	r0, [pc, r0]
      cc649c:	e3500000 	cmp	r0, #0
      cc64a0:	012fff1e 	bxeq	lr
      cc64a4:	e5901000 	ldr	r1, [r0]
      cc64a8:	e5911028 	ldr	r1, [r1, #40]	; 0x28
      cc64ac:	e12fff11 	bx	r1
      cc64b0:	03057e60 	.word	0x03057e60
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    因此,排除了没有将代码打包进去so库可能性。

    3.检查是否加载对应cpu的so库问题

    3.1 缺少cpu 即abi支持so库

    根据捕捉到日志,可知当该设备支持armeabi-v7a,armeabi

    查看下渠道包apk, 已经带有armeabi-v7a 的支持,因此排除了该问题。

    若是调试过程遇到该问题,则可以通过执行:
    adb shellcat /proc/cpuinfo 查看下支持abi,如下图所示:
    在这里插入图片描述

    3.2 调用相应方法前没有加载so库

    检查调用nativeOnIdle() 是在GLThread 异步线程中,但加载so库的过程是主线程中。其次,调用前并没有检查是否so库加载好的逻辑,是该原因导致。

    解决方式: 调用前,检查so库是否已经load状态。

  • 相关阅读:
    DAO和增删改查通用方法-BasicDao
    hot100-相交链表
    TextAttack配置中遇到的问题(TAADpapers)
    实用设计模式实战:工厂+策略
    如何克服微服务测试的挑战并最大化收益?
    零基础学Java(1)初识Java程序
    HTML+CSS-项目:学成在线
    【示波器专题】示波器输入匹配电阻1MΩ和50Ω的选择
    QT day1
    Sentinel源码剖析之常用限流算法原理实现
  • 原文地址:https://blog.csdn.net/hexingen/article/details/126836738