使用simpleperf分析Android性能时内核模块符号读取失败的疑问
问题重现
执行simpleperf命令时出现如下警告:
/mnt/androidwritable # simpleperf report --print-event-count |head -n 10 simpleperf W dso.cpp:450] failed to read symbols from [zram]: File not found simpleperf W dso.cpp:450] failed to read symbols from [ufs_qcom]: File not found simpleperf W dso.cpp:450] failed to read symbols from [qcom_dma_heaps]: File not found simpleperf W dso.cpp:450] failed to read symbols from [mem_hooks]: File not found simpleperf W dso.cpp:450] failed to read symbols from [qcom_iommu_util]: File not found simpleperf W dso.cpp:450] failed to read symbols from [arm_smmu]: File not found simpleperf W dso.cpp:450] failed to read symbols from [sched_walt]: File not found simpleperf W dso.cpp:450] failed to read symbols from [msm_rtb]: File not found
指定--symfs参数后问题依旧,原因可能有以下几点:
可能的原因及解决方法
内核模块文件命名/路径不匹配
simpleperf查找内核模块时,会严格匹配带.ko后缀的真实文件名(比如zram.ko),且要求文件路径层级和系统加载模块的路径一致(例如系统中模块存放在/lib/modules/<kernel_version>/下,symfs中也要保持相同的层级结构)。如果--symfs指向的目录里没有对应.ko文件,或者路径不对,就会触发报错。
解决:检查symfs目录下是否存在对应模块的.ko文件,且路径层级和系统一致。内核模块被剥离调试符号
多数厂商发布的内核模块会默认用strip工具剥离调试符号,此时即使模块文件存在,simpleperf也无法读取到符号,报错信息会显示“File not found”(这个提示有误导性,实际是符号不存在)。
解决:使用带有完整调试符号的内核模块镜像,需从设备厂商获取对应版本的debug内核包,或自行编译带调试信息的内核模块。--symfs参数使用错误--symfs需要指向包含整个系统符号文件的根目录,而非单独的模块目录。比如系统内核模块路径为/lib/modules/5.4.0/,则--symfs要指向包含lib/目录的根路径,不能直接指向/lib/modules/5.4.0/。
解决:调整参数指向正确的符号根目录,例如simpleperf report --print-event-count --symfs /path/to/symbol_root,其中symbol_root下有完整的lib/modules/层级。内核版本不匹配
symfs中的内核模块版本如果和设备当前运行的内核版本不一致,simpleperf无法正确解析符号。
解决:通过uname -r查看设备内核版本,确保symfs中的模块是对应版本的带符号文件。
内容的提问来源于stack exchange,提问作者Jun

