KGDB与串口GDB调试无法设置断点问题排查
解决kgdb无法设置断点的问题
嘿,你碰到的这个断点插不进去的问题,我之前调试内核时也遇到过,大概率是**内核地址空间随机化(KASLR)**在搞鬼,再加上可能的内核镜像匹配问题,咱们一步步来解决:
1. 核心问题:KASLR让符号地址"跑偏"了
Ubuntu 17.10默认开启了KASLR(对应内核配置CONFIG_RANDOMIZE_BASE=y),启动时会随机偏移内核的加载地址。你在gdb里从vmlinux拿到的oom_kill_process静态地址0xffffffff811cc0e0,和test机器上实际运行的内核中该函数的真实地址根本对不上,自然就提示无法访问内存地址了。
而且你给test机器配置的grub参数里只加了kgdbwait和kgdboc,没关闭KASLR,这是最关键的疏漏。
2. 一步步解决问题
第一步:给test机器关闭KASLR
修改test机器的grub启动参数,在linux行的末尾添加nokaslr,强制内核以固定地址加载:
linux /boot/vmlinuz-4.15.0 root=UUID=2f89c974-19ab-4b5f-96cc871c8aded5b ro quiet splash $vt_handoff kgdbwait kgdboc=ttyS0,115200 nokaslr
修改完成后重启test机器,让新的启动参数生效。
第二步:确认两台机器的内核镜像完全一致
必须保证development机器上的/usr/src/linux-4.15/vmlinux和test机器上运行的内核是同一编译产物:
- 先在test机器上执行
md5sum /boot/vmlinuz-4.15.0,记录下哈希值; - 再到development机器上执行
md5sum /usr/src/linux-4.15/vmlinux,对比两个哈希值是否一致。 - 如果不一致,要么把test机器编译内核时生成的
vmlinux文件拷贝到development机器,要么在development机器上使用和test完全相同的.config重新编译内核,确保符号表的地址完全匹配。
第三步:重新连接gdb尝试设置断点
重启test机器后,回到development机器重新启动gdb:
gdb /usr/src/linux-4.15/vmlinux
连接目标后再次尝试设置断点:
target remote /dev/ttyS0 break oom_kill_process continue
这时候应该就能正常插入断点了。
额外小技巧:如果问题仍存在
要是按上面的步骤操作后还是不行,你可以在test机器的kdb中执行sym oom_kill_process,查看该函数的真实运行地址,然后在gdb里用break *0x真实地址的方式设置断点,这样就能确认是不是符号表不匹配的问题了。
内容的提问来源于stack exchange,提问作者fremmi
相关产品推荐
相关产品推荐

