Chinaunix首页 | 论坛 | 博客
  • 博客访问: 235850
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 296
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-22 11:52
文章分类

全部博文(31)

文章存档

2018年(3)

2017年(11)

2016年(12)

2015年(5)

我的朋友

分类: LINUX

2015-08-08 14:35:38

   
最近在查内核代码的一个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中有显示的函数,如果没有显示的,就老老实实的单独编译一个内核模块也是挺方便的


阅读(2749) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~