解决Clang+LLVM编译的Kernel多余.LBB符号导致Call Trace不方便查阅的问题

内容纲要

最近因为科研需求需要在全志D1开发板做性能的Evaluation,但是这个开发板的驱动用GCC编译是正常,而使用Clang+LLVM编译时存在许多问题,SD卡、网卡、USB全都有问题,因此考虑自己做一些修复。

但是由于硬件不方便在QEMU模拟,开发板的调试全靠串口输出,因此比较困难,但是一个大问题是LLVM编译的内核多了许多.LBB符号,导致Call Trace大概会长这样:

[    2.666348] [<ffffffff80004ecc>] .LBB2_1+0x20/0x2c
[    2.671152] [<ffffffff808f2c64>] dump_stack_lvl+0x4a/0x66
[    2.676562] [<ffffffff808f2c98>] .LBB4_1+0x10/0x18
[    2.681360] [<ffffffff808f27ce>] .LBB4_48+0x22/0x3e
[    2.686245] [<ffffffff806f61c2>] mmc_read_switch+0x0/0x1e
[    2.691657] [<ffffffff806f6640>] .LBB8_135+0x16c/0x2d8
[    2.696803] [<ffffffff806f6396>] .LBB7_21+0x66/0xee
[    2.701690] [<ffffffff806ef754>] .LBB58_43+0x130/0x16e
[    2.706835] [<ffffffff80026c3e>] process_one_work+0x160/0x16a
[    2.712595] [<ffffffff80026fc2>] .LBB80_58+0x190/0x2aa
[    2.717743] [<ffffffff8002c1fa>] .LBB43_15+0x92/0x9a
[    2.722721] [<ffffffff80003260>] ret_from_exception+0x0/0xc

而同样的地方,GCC下却是这样的:

[    2.655550] [<ffffffff80004842>] dump_backtrace+0x1c/0x24
[    2.660960] [<ffffffff8080a140>] dump_stack_lvl+0x40/0x58
[    2.666372] [<ffffffff8080a16c>] dump_stack+0x14/0x1c
[    2.671429] [<ffffffff80807800>] panic+0xfc/0x2b6
[    2.676140] [<ffffffff8063b912>] mmc_sd_setup_card+0x66/0x6a
[    2.681810] [<ffffffff8063b9f6>] mmc_sd_init_card+0xe0/0x936
[    2.687476] [<ffffffff8063c3e4>] mmc_attach_sd+0xac/0x11a
[    2.692884] [<ffffffff80634c7e>] mmc_rescan+0x240/0x278
[    2.698115] [<ffffffff80020bb4>] process_one_work+0x13c/0x27c
[    2.703870] [<ffffffff80020d70>] worker_thread+0x7c/0x31c
[    2.709275] [<ffffffff80027318>] kthread+0x100/0x112
[    2.714253] [<ffffffff80003058>] ret_from_exception+0x0/0xc

可以很明显看到,这样的符号十分不利于我们快速找到对应的函数。后来经过2老师指点,Call Trace输出的函数名是通过栈中的返回地址向上寻找到符号表中最接近的符号来实现的。

而2老师之前也遇到过类似问题,也提供了解决方法,就是修改Kernel代码的scripts/kallsyms.c,在is_ignored_symbol函数中有一个数组存储了ignored_prefixes,我们把.LBB加入即可,这样在最终生成的内核中就会删除对应的符号。

这样,Clang+LLVM编译的Kernel输出的Call Trace就与之前GCC输出的结果一样方便查阅了。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

Back to Top