dlsym是什么?

dlsym是一个计算机函数,功能是根据动态链接库操作句柄与符号,返回符号对应的地址,不但可以获取函数地址,也可以获取变量地址

见:采用dlopen、dlsym、dlclose加载动态链接库【总结】

 

出现问题

给Android添加system_service的代码时,在HAL层出现问题;

源代码

/* Get the address of the struct hal_module_info. */
    const char *sym = HAL_MODULE_INFO_SYM_AS_STR;
    hmi = (struct hw_module_t *)dlsym(handle, sym);
    if (hmi == NULL) {
        ALOGE("load: couldn't find symbol %s", sym);
        status = -EINVAL;
        goto done;
    }

错误日志打印:

2021-06-14 21:23:58.084 1828-1828/system_process I/HAL: 1.1 hardware load() path:/system/lib64/hw/freg.default.so
2021-06-14 21:23:58.084 1828-1828/system_process I/HAL: 2 hardware load() 
2021-06-14 21:23:58.084 1828-1828/system_process E/HAL: load: couldn't find symbol HMI

结果表明,库“freg.default.s”没有HMI符号。

 

排查步骤

(1)首先使用grep查看“.os”是否有HMI,如下:

gs@aigo:~/nvme_1T/android9.0.0_35/out/target/product/generic_x86_64/system/lib64/hw$ ls
android.hidl.memory@1.0-impl.so  audio.a2dp.default.so  camera.default.so  camera.usb.default.so  freg.default.so  input.evdev.default.so
gs@aigo:~/nvme_1T/android9.0.0_35/out/target/product/generic_x86_64/system/lib64/hw$ grep -rn HMI
Binary file input.evdev.default.so matches
Binary file camera.default.so matches
Binary file audio.a2dp.default.so matches
Binary file camera.usb.default.so matches
gs@aigo:~/nvme_1T/android9.0.0_35/out/target/product/generic_x86_64/system/lib64/hw$

上面的结果现实,“freg.default.s”没有HMI符号。

(2)使用查看符号表命令;

查看符号表的命令:linux 下查看 so库 符号表

gs@aigo:~/nvme_1T/android9.0.0_35/out/target/product/generic_x86_64/system/lib64/hw$ nm -D freg.default.so 
                 U __android_log_print
0000000000002008 A __bss_start
                 U close
                 U __cxa_atexit
                 U __cxa_finalize
0000000000002008 A _edata
0000000000002008 A _end
                 U __errno
                 U free
                 U malloc
                 U __open_2
                 U read
                 U __register_atfork
                 U __stack_chk_fail
                 U strcmp
                 U strerror
                 U __write_chk
gs@aigo:~/nvme_1T/android9.0.0_35/out/target/product/generic_x86_64/system/lib64/hw$ 
gs@aigo:~/nvme_1T/android9.0.0_35/out/target/product/generic_x86_64/system/lib64/hw$ nm -D input.evdev.default.so 
                 U __android_log_assert
                 U __android_log_print
0000000000004118 A __bss_start
                 U __cxa_atexit
                 U __cxa_finalize
0000000000004118 A _edata
0000000000004120 A _end
0000000000004010 D HMI
                 U memcpy
                 U pthread_create
                 U pthread_setspecific
                 U __register_atfork
                 U __stack_chk_fail
                 U strcmp
                 U _ZdlPv
0000000000001530 T _ZN7android11EvdevModule12notifyReportEP12input_report
0000000000001410 T _ZN7android11EvdevModule4initEv
0000000000001510 T _ZN7android11EvdevModule4loopEv
0000000000001300 T _ZN7android11EvdevModuleC1EPNS_18InputHostInterfaceE
0000000000001300 T _ZN7android11EvdevModuleC2EPNS_18InputHostInterfaceE
                 U _ZN7android8InputHubC1ERKNSt3__110shared_ptrINS_22InputCallbackInterfaceEEE
                 U _ZNKSt3__119__shared_weak_count13__get_deleterERKSt9type_info
0000000000001840 W _ZNSt3__114__thread_proxyINS_5tupleIJNS_10unique_ptrINS_15__thread_structENS_14default_deleteIS3_EEEEMN7android11EvdevModuleEFvvEPS8_EEEEEPvSD_
                 U _ZNSt3__115__thread_structC1Ev
                 U _ZNSt3__115__thread_structD1Ev
                 U _ZNSt3__119__shared_weak_count14__release_weakEv
                 U _ZNSt3__119__shared_weak_countD2Ev
                 U _ZNSt3__119__thread_local_dataEv
0000000000001750 W _ZNSt3__120__shared_ptr_emplaceIN7android18InputDeviceManagerENS_9allocatorIS2_EEE16__on_zero_sharedEv
0000000000001760 W _ZNSt3__120__shared_ptr_emplaceIN7android18InputDeviceManagerENS_9allocatorIS2_EEE21__on_zero_shared_weakEv
                 U _ZNSt3__120__throw_system_errorEiPKc
                 U _ZNSt3__16threadD1Ev
                 U _Znwm
                 U _ZSt9terminatev
                 U _ZTVN7android18InputDeviceManagerE
                 U _ZTVN7android9InputHostE
0000000000003c60 V _ZTVNSt3__120__shared_ptr_emplaceIN7android18InputDeviceManagerENS_9allocatorIS2_EEEE
gs@aigo:~/nvme_1T/android9.0.0_35/out/target/product/generic_x86_64/system/lib64/hw$

(3)查看代码;

查看代码,对比了 hardware/libhardware/modules/ 目录下的其他模块的 Android.bp 文件,发现多了个  "-fvisibility=hidden",  如下面所示,删除掉这句。

这是从其他的文件中拷贝过来的,因此引入了这个问题。

    cflags: [
        "-Wall",
        "-Wextra",
        "-Werror",
        "-fvisibility=hidden",
    ],

(4)验证问题,编译后,重新查看符号表。如下:

gs@aigo:~/nvme_1T/android9.0.0_35/out/target/product/generic_x86_64/system/lib64/hw$ nm -D freg.default.so 
                 U __android_log_print
0000000000003108 A __bss_start
                 U close
                 U __cxa_atexit
                 U __cxa_finalize
0000000000003108 A _edata
000000000000310c A _end
                 U __errno
                 U free
0000000000003010 D HMI
                 U malloc
                 U __open_2
                 U read
                 U __register_atfork
                 U __stack_chk_fail
                 U strcmp
                 U strerror
                 U __write_chk
gs@aigo:~/nvme_1T/android9.0.0_35/out/target/product/generic_x86_64/system/lib64/hw$ 

可以看到,有 “HMI” 了,至此,问题解决。