问题描述
在研究 kprobes 时,成功编译出几次 demo 模块后再重新编译时突然报错,错误信息如下:
cc1: error: code model kernel does not support PIC mode
命令行操作记录摘录如下:
longyu@virt-debian10:~/kprobes$ make
make[1]: 进入目录“/usr/src/linux-headers-4.19.0-8-amd64”
CC [M] /home/longyu/kprobes/kprobe_example.o
cc1: error: code model kernel does not support PIC mode
make[4]: *** [/usr/src/linux-headers-4.19.0-8-common/scripts/Makefile.build:315:/home/longyu/kprobes/kprobe_example.o] 错误 1
make[3]: *** [/usr/src/linux-headers-4.19.0-8-common/Makefile:1537:_module_/home/longyu/kprobes] 错误 2
make[2]: *** [Makefile:146:sub-make] 错误 2
make[1]: *** [Makefile:8:all] 错误 2
make[1]: 离开目录“/usr/src/linux-headers-4.19.0-8-amd64”
make: *** [Makefile:14:modules] 错误 2
解决过程
1. 检查 Makefile 文件
这个编译选项可能是 Makefile 文件中配置的,我首先检查 Makefile 文件,没有发现相关的内容。
2. 搜索互联网
搜索互联网发现这个问题有人给出了一种修改 EXTRA_CFLAGS 的解决方案,实际是在 EXTRA_CFLAGS 中添加 -fno-pie 选项,修改后重新编译果然不报错了。
加载的时候却报 mcount 符号找不到的问题,一度让我怀疑 gcc 可能有问题了。
3. 检查 gcc 是否能够正常工作
经过上面步骤的排查,我怀疑 gcc 有问题,编译了一个 xxx.c 后报了如下错误:
tunpong.c:79:1: fatal error: error writing to /tmp/ccyQFpRG.s: 设备上没有空间
看报错应该是 /tmp 目录满了,执行 df 查看确认 /tmp 目录已经没有空间可用了。df 命令的输出信息如下:
longyu@virt-debian10:~/kprobes$ df -h /tmp
文件系统 容量 已用 可用 已用% 挂载点
/dev/vda1 3.6G 3.5G 0 100% /
4. mount tmpfs 确认是 /tmp 目录满了的原因
对于这种情况,可以通过挂载一个 tmpfs 到 /tmp 来完成暂时的扩容工作,我通过执行如下命令挂载 tmpfs 到 /tmp 中:
sudo mount -t tmpfs tmpfs /tmp
挂载完成后,重新编译模块,这次能够成功编译并且能够成功加载!操作记录如下:
longyu@virt-debian10:~/kprobes$ sudo mount -t tmpfs tmpfs /tmp
longyu@virt-debian10:~/kprobes$ make
make[1]: 进入目录“/usr/src/linux-headers-4.19.0-8-amd64”
Building modules, stage 2.
MODPOST 1 modules
make[1]: 离开目录“/usr/src/linux-headers-4.19.0-8-amd64”
这个命令行中首先挂载 tmpfs 到 /tmp 以对 /tmp 进行扩容,扩容后模块能够成功编译了(恢复之前对 EXTRA_CFLAGS 的修改)!
kprobe 的问题
我使用的 kprobe demo 中对 do_sys_open 函数进行了探测,在此函数执行的前后进行打印。结果运行了一会后,虚拟机卡住了,新的 ssh 连接能够正常建立但是进入不了终端,这让我怀疑是否 kprobe 功能存在 bug。
一通折腾后发现根分区满了,du -hs /* 发现 /var 目录占了很多空间,进一步的追踪发现 /var/log 目录占了很多空间,才发现是 do_sys_open 调用的太过频繁导致系统不断向 /var/log/ 中写入日志,从而在短时间内将我本来就微薄的存储空间压榨殆尽,导致出现我以为的系统卡住的问题。
我直接在我的宿主机 linux 环境中进行测试,我的宿主机上 /var/ 目录有单独的挂载点,大小为 15G,可用空间 10G 左右,这次测试就没有这个问题了。
总结
有些问题的表面现象与真实的情况可能差距很大,对于这样的问题我们要不断的质疑并用实际的操作来验证,如此才能不断的向问题的真相逼近!
对于网上给出的答案,我们一定要进行实际的测试来得出结论,不盲目相信。这就是所谓的纸上得来终觉浅,绝知此事要躬行的道理!