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” 了,至此,问题解决。