Linux 4.14.304执行perf record触发Segmentation Fault求助
4.14内核执行
perf record触发内核Oops崩溃,5.10内核正常 执行perf record时触发内核Oops,最终perf进程段错误退出,报错日志如下:
# perf record [ 5574.631385] Unable to handle kernel paging request at virtual address ffffff80087497a9 [ 5574.639299] Mem abort info: [ 5574.640708] Exception class = DABT (current EL), IL = 32 bits [ 5574.647987] SET = 0, FnV = 0 [ 5574.651066] EA = 0, S1PTW = 0 [ 5574.651853] Data abort info: [ 5574.655239] ISV = 0, ISS = 0x00000007 [ 5574.659753] CM = 0, WnR = 0 [ 5574.663848] swapper pgtable: 4k pages, 39-bit VAs, pgd = ffffff8008812000 [ 5574.670636] [ffffff80087497a9] *pgd=000000007bffe003, *pud=000000007bffe003, *pmd=000000007bffb003, *pte=0000000000000000 [ 5574.681598] Internal error: Oops: 96000007 [#13] PREEMPT SMP [ 5574.687252] Modules linked in: rp3(O) csd(O) ultxrxcccorr(O) ultxrxcc(O) tmr(O) swi(O) str(O) pcs(O) mes(O) jsd(O) esds(O) esdl(O) esdc(O) esdb(O) dul(O) ddl(O) ctx_bank(O) ctx(O) c) [ 5574.732494] Process perf (pid: 3337, stack limit = 0xffffff8014978000) [ 5574.736844] CPU: 2 PID: 3337 Comm: perf Tainted: G D O 4.14.304 #1 [ 5574.743959] Hardware name: Made SoC (DT) [ 5574.750037] task: ffffffc078f36c00 task.stack: ffffff8014978000 [ 5574.755950] pc : get_ctx+0x0/0x50 [ 5574.759257] lr : find_get_context.isra.0+0x194/0x288 [ 5574.764211] sp : ffffff801497bd70 pstate : 00000145 [ 5574.766821] x29: ffffff801497bd70 x28: 0000000000000000 [ 5574.774374] x27: 0000000000000000 x26: 0000000000000000 [ 5574.779678] x25: ffffffc07b10fe80 x24: 0000000000000000 [ 5574.783593] x23: 0000000000000004 x22: 00000000ffffffff [ 5574.790278] x21: ffffffc07b10fe80 x20: ffffff8008749729 [ 5574.795583] x19: ffffff8008749721 x18: 0000000000000001 [ 5574.800887] x17: 0000007f9ddfd300 x16: ffffff800812aba0 [ 5574.806191] x15: 0000000000000000 x14: 0000000000000000 [ 5574.810887] x13: 0000000300000002 x12: 0000000100000000 [ 5574.815748] x11: 0000000000000040 x10: ffffff80087f2b30 [ 5574.819481] x9 : ffffffc07898d810 x8 : ffffffc06dc77b78 [ 5574.824777] x7 : 0000000000000000 x6 : ffffffc06dc77b50 [ 5574.832678] x5 : ffffffc06dc77b80 x4 : ffffff8008768708 [ 5574.837982] x3 : 0000000000000001 x2 : ffffffc078f36c00 [ 5574.843286] x1 : 0000000000400100 x0 : ffffff8008749721 [ 5574.848591] Call trace: [ 5574.851029] get_ctx+0x0/0x50 [ 5574.853989] SyS_perf_event_open+0x43c/0xdc0 [ 5574.858251] el0_svc_naked+0x34/0x38 [ 5574.859214] Code: f9414c21 9411391a 17fffff5 d503201f (b9408801) [ 5574.867895] ---[ end trace 6ee5d32e2ee2eebe ]--- Segmentation fault ftp@made-Node0:/var/tmp#
已知基于5.10版本的镜像中perf record可正常运行,但必须使用4.14版本内核。
报错关键点分析
- 内存访问错误:内核尝试读取虚拟地址
ffffff80087497a9时触发页请求失败,该地址对应的PTE为空,说明访问了未映射的内存区域 - 调用栈定位:崩溃发生在
get_ctx函数入口,由find_get_context调用,最终追溯到perf_event_open系统调用,说明perf事件上下文查找过程中出现无效内存访问 - 内核污染标记:
Tainted: G D O中的O表示加载了第三方内核模块,已加载的模块包含ctx、ctx_bank等与上下文管理相关的自定义模块,大概率是兼容性问题根源
排查方向
- 卸载所有第三方自定义模块后重新执行
perf record,确认是否是模块冲突导致的崩溃 - 核对自定义模块中
get_ctx函数的实现,检查传入的指针(如x0寄存器的值ffffff8008749721)是否为合法内核内存地址,排查是否存在指针传递错误 - 对比4.14与5.10内核中
perf_event_open及上下文查找相关的代码逻辑,检查4.14内核是否缺少5.10中已修复的内存访问问题补丁 - 确保perf工具是基于当前4.14内核源码编译的版本,避免工具与内核版本不匹配引发异常
- 检查自定义模块在4.14内核上的适配逻辑,确认是否针对perf子系统的上下文管理做了正确处理,5.10版本可能做了适配但4.14版本遗漏
内容的提问来源于stack exchange,提问作者qingchuan wang
相关产品推荐
相关产品推荐

