最近在查内核代码的一个bug,趁这个机会总结一下写内核代码以来的各种调试方式吧
1.prink这种的可能就是入门级别的了,不过简单方便易用,写自己的小程序的时候可以用这种方式
2.写内核代码很容易引起内核panic,这个时候crash 的分析就显得特别重要了,能通过分析kdump采集到的panic信
息定位到具体哪行代码,哪一个变量的引起的。要是能懂一丁点汇编的话,这个分析做起来更是手到擒来,不过
写内核代码的谁不懂点小汇编呢,跟命令objdump 出来的结果一样,很好懂的。
3.jprobe ,我觉得这个东西最好用,想了解一个函数具体发生了什么,就用这个东西吧,这个东西不仅能用来调试,也可以实现某
些功能的,我了解到这个东西要是因为某一个功能常规办法没法实现,才借用了这个东西实现。既然都写到这里了,那就顺便记录
一下发现这个好东西的原动力吧。
这个功能就是要统计linux 网络协议栈中conntrack表中已经destroy的连接的packet /bytes,当然把/proc/sys/net/netfilter/nf_conntrack_acct
置1之后连接表就会有记录packets/bytes的信息(我是在3.14的内核中做的测试,默认这个值为0,好像2.x的内核这个值默认是1的),我只
需要能抓到连接表的destroy事件,赶在其destroy之前,记录到本地就行了,一开始,我是想到事件通知链的,查了一下内核的事件通知链,
就三个 ,一个是ipv4地址改变,一个是ipv6地址改变,一个是网 络设备状态改变,好像都不能用。跟ct相关的事件通知链,是nf模块自己实
现的,在ecache中实现的注册函数,在netlink模块中调用,但是对于一个net只能有一个回调函数,已经被ctnetlink调用了,因此我写的模块
不能调用了,考虑了一整天,改源码这种方式不太可行,参考ecache自己写register函数也不太可行,为了这么一个功能,花那么大的力气,
不值得。后面在cu上面提问,大神提供了jprobe的方式,最后就是用这种方式实现了destroy函数的劫持,在内核的destroy函数调用之前,
先调用自定义的函数,就把连接的packets/bytes记录下来了. 从此之后就发现jprobe的好处了,能劫持函数,就能做好多事情了,之后的调试
就经常用到。
4.dump_statck() 这是一个函数,可以打印函数调用的堆栈信息,如果只是想看看函数调用顺序,这个绝对比下面的双机调试,单步
执行简单多了。
5.kgdb 双机调试,环境搭好后,跟gdb一样好用,可以断点,单步调,打印变量值,反正gdb能做,kgdb都能做,不过比较麻烦
要双机,之前在虚拟机上面搭过一次环境,感觉还挺好用的,能动态多次调试。用物理机的话,好像还要接线,更麻烦。
具体上面的方式怎么用,就不用记录了,反正开发机,我一般都会配好kdump+crash 的环境的,crash的分析,jprobe,dump_stack
这几种方式用得比较多,至于双机嘛,印象中只用过一次,具体怎么用现在肯定是忘记了,不过前面的那些够用了,等那天需要双机
的时候,估计再找一些资料学习学习就好了
再补充一点,jprobe只能hack 在/proc/kallsyms中有显示的函数,如果没有显示的,就老老实实的单独编译一个内核模块也是挺方便的
阅读(2718) | 评论(0) | 转发(0) |