红帽Linux故障定位技术详解与实例(4)

红帽Linux故障定位技术详解与实例(4)

在线故障定位就是在故障发生时, 故障所处的操作系统环境仍然可以访问,故障处理人员可通过console, ssh等方式登录到操作系统上,在shell上执行各种操作命令或测试程序的方式对故障环境进行观察,分析,测试,以定位出故障发生的原因。

AD:2014WOT全球软件技术峰会北京站 课程视频发布

6、使用kprobe来观察内核函数的执行实例

kprobe是SystemTap对内核函数进行probing的功能在内核中的实现,由于内核中提供了正式的API来使用kprobe,所以对很多内核程序员来说,也许直接使用kprobe比使用SystemTap更方便. 内核中提供了三种类型的kprobe处理函数,分别是jprobe, kprobe, kretprobe, 下面的代码用这三个probe观察在TCP/IP的arp_process函数执行中对ip_route_input()调用的返回结果.这个代码还展示了在同一个函数probe的Entry handler和Ret handler之间共享参数的方法. 代码如下:

  1. arp_probe.c /*
  2. * arp_probe.c, by Qianfeng Zhang ([email protected])
  3. */
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. #include
  10. #include
  11. #include
  12. MODULE_AUTHOR("[email protected]");
  13. MODULE_DESCRIPTION("A module to track the call results of ip_route_input() inside arp_process using jprobe and kretprobe");
  14. MODULE_LICENSE("GPL");
  15. static int j_arp_process(struct sk_buff *skb)
  16. {
  17. struct net_device *dev = skb->dev;
  18. struct in_device *in_dev;
  19. int no_addr, rpf;
  20. in_dev = in_dev_get(dev);
  21. no_addr = ( in_dev->ifa_list == NULL );
  22. rpf = IN_DEV_RPFILTER(in_dev);
  23. in_dev_put(in_dev);
  24. printk("\narp_process() is called with interface device %s, in_dev(no_addr=%d,rpf=%d) \n", dev->name, no_addr, rpf);
  25. jprobe_return();
  26. return(0);
  27. };
  28. static int j_fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
  29. struct net_device *dev, __be32 *spec_dst, u32 *itag, u32 mark)
  30. {
  31. printk("fib_validate_source() is called with dst=0x%x, oif=%d \n", dst, oif);
  32. jprobe_return();
  33. return(0);
  34. };
  35. static struct jprobe my_jp1 = {
  36. .entry = j_arp_process,
  37. .kp.symbol_name = "arp_process"
  38. };
  39. static struct jprobe my_jp2 = {
  40. .entry = j_fib_validate_source,
  41. .kp.symbol_name = "fib_validate_source"
  42. };
  43. static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
  44. {
  45. printk("Calling: %s()\n", ri->rp->kp.symbol_name);
  46. return(0);
  47. };
  48. static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
  49. {
  50. int eax;
  51. eax = regs->ax & 0xffff ;
  52. printk("Returning: %s() with a return value: 0x%lx(64bit) 0x%x(32bit)\n", ri->rp->kp.symbol_name, regs->ax, eax);
  53. return(0);
  54. };
  55. static int fib_lookup_entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
  56. {
  57. struct fib_result *resp;
  58. resp = (struct fib_result *) regs->dx;
  59. printk("Calling: %s()\n", ri->rp->kp.symbol_name);
  60. *((struct fib_result **)ri->data) = resp;
  61. return(0);
  62. };
  63. static int fib_lookup_return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
  64. {
  65. struct fib_result *resp;
  66. int eax;
  67. eax = regs->ax & 0xffff ;
  68. resp = *((struct fib_result **) ri->data);
  69. printk("Returning: fib_lookup() with a return value: 0x%lx(64bit) 0x%x(32bit), result->type: %d\n", regs->ax, eax, resp->type);
  70. return(0);
  71. }
  72. static struct kretprobe my_rp1 = {
  73. .handler = return_handler,
  74. .entry_handler = entry_handler,
  75. .kp.symbol_name = "ip_route_input_slow"
  76. };
  77. static struct kretprobe my_rp2 = {
  78. .handler = return_handler,
  79. .entry_handler = entry_handler,
  80. .kp.symbol_name = "fib_validate_source"
  81. };
  82. static struct kretprobe my_rp3 = {
  83. .handler = fib_lookup_return_handler,
  84. .entry_handler = fib_lookup_entry_handler,
  85. .kp.symbol_name = "fib_lookup",
  86. .data_size = sizeof(struct fib_result *)
  87. };
  88. static int __init init_myprobe(void)
  89. {
  90. int ret;
  91. printk("RTN_UNICAST is %d\n", RTN_UNICAST);
  92. if ( (ret = register_jprobe(&my_jp1)) < 0) {
  93. printk("register_jprobe %s failed, returned %d\n", my_jp1.kp.symbol_name, ret);
  94. return(-1);
  95. }
  96. if ( (ret = register_jprobe(&my_jp2)) < 0) {
  97. printk("register_jprobe %s failed, returned %d\n", my_jp2.kp.symbol_name, ret);
  98. return(-1);
  99. }
  100. if ( (ret = register_kretprobe(&my_rp1)) < 0 ) {
  101. printk("register_kretprobe %s failed, returned %d\n", my_rp1.kp.symbol_name, ret);
  102. unregister_jprobe(&my_jp1);
  103. unregister_jprobe(&my_jp2);
  104. return(-1);
  105. }
  106. if ( (ret = register_kretprobe(&my_rp2)) < 0 ) {
  107. printk("register_kretprobe %s failed, returned %d\n", my_rp2.kp.symbol_name, ret);
  108. unregister_jprobe(&my_jp1);
  109. unregister_jprobe(&my_jp2);
  110. unregister_kretprobe(&my_rp1);
  111. return(-1);
  112. }
  113. if ( (ret = register_kretprobe(&my_rp3)) < 0 ) {
  114. printk("register_kretprobe %s failed, returned %d\n", my_rp3.kp.symbol_name, ret);
  115. unregister_jprobe(&my_jp1);
  116. unregister_jprobe(&my_jp2);
  117. unregister_kretprobe(&my_rp1);
  118. unregister_kretprobe(&my_rp2);
  119. return(-1);
  120. }
  121. return 0;
  122. }
  123. static void __exit rel_myprobe(void)
  124. {
  125. unregister_jprobe(&my_jp1);
  126. unregister_jprobe(&my_jp2);
  127. unregister_kretprobe(&my_rp1);
  128. unregister_kretprobe(&my_rp2);
  129. unregister_kretprobe(&my_rp3);
  130. }
  131. module_init(init_myprobe);
  132. module_exit(rel_myprobe);
  133. Makefile obj-m += arp_probe.o
  134. Making #> make -C /usr/src/kernels/2.6.32-71.el6.x86_64/ M=`pwd` modules

Linux故障定位技术详解与实例的内容介绍完了,希望通过本文红帽Linux故障定位技术的学习能对你有所帮助!

原文地址:http://beareyes.com.cn/2/lib/201109/27/20110927182_0.htm

时间: 2024-10-24 12:24:58

红帽Linux故障定位技术详解与实例(4)的相关文章

红帽Linux故障定位技术详解与实例(2)

红帽Linux故障定位技术详解与实例(2) 2011-09-28 14:26 圈儿 BEAREYES.COM 我要评论(0) 字号:T | T 在线故障定位就是在故障发生时, 故障所处的操作系统环境仍然可以访问,故障处理人员可通过console, ssh等方式登录到操作系统上,在shell上执行各种操作命令或测试程序的方式对故障环境进行观察,分析,测试,以定位出故障发生的原因. AD:2014WOT全球软件技术峰会北京站 课程视频发布 3.内核故障情形及处理 (1)内核panic panic是内

红帽Linux故障定位技术详解与实例(1)

红帽Linux故障定位技术详解与实例(1) 2011-09-28 14:26 圈儿 BEAREYES.COM 我要评论(0) 字号:T | T 在线故障定位就是在故障发生时, 故障所处的操作系统环境仍然可以访问,故障处理人员可通过console, ssh等方式登录到操作系统上,在shell上执行各种操作命令或测试程序的方式对故障环境进行观察,分析,测试,以定位出故障发生的原因. AD:2014WOT全球软件技术峰会北京站 课程视频发布 红帽Linux故障定位技术详解与实例是本文要介绍的内容,主要

红帽Linux故障定位技术详解与实例(3)

红帽Linux故障定位技术详解与实例(3) 在线故障定位就是在故障发生时, 故障所处的操作系统环境仍然可以访问,故障处理人员可通过console, ssh等方式登录到操作系统上,在shell上执行各种操作命令或测试程序的方式对故障环境进行观察,分析,测试,以定位出故障发生的原因. AD:2014WOT全球软件技术峰会北京站 课程视频发布 5.用kdump工具内核故障定位实例 A) 部署Kdump 部署 kdump 收集故障信息的步骤如下: (1)设置好相关的内核启动参数 在 /boot/grub

Linux磁盘阵列技术详解(二)--raid 1创建

我在Linux磁盘阵列技术详解(一)里已经详细介绍了几种RAID磁盘阵列方式,原理以及创建raid 0 的详细步骤.那么这篇文档就着重讲解如何创建raid 1的技术: 步骤如下: ① 分区 同样我们还是以一块硬盘的不同分区为例,实际工作中应该是不同的硬盘才对. 具体分区步骤不再赘述! 分区后结果如下图所示: ② 创建raid 1 mdadm -C -v /dev/md1 -l 1 -n 2 -x 1 /dev/sdc1 /dev/sdc2 /dev/sdc3 或者 mdadm -C -v /de

Protocol Buffer技术详解(Java实例)

Protocol Buffer技术详解(Java实例) 该篇Blog和上一篇(C++实例)基本相同,只是面向于我们团队中的Java工程师,毕竟我们项目的前端部分是基于Android开发的,而且我们研发团队中目前主要使用的开发语言就是C++.Java和Python,其中Python主要用于编写各种工具程序.然而为了保证该篇Blog的完整性和独立性,我仍然会将上一篇Blog中已经出现的内容再一次赘述,同时对于Java中特有的部分也会着重介绍.          一.生成目标语言代码.      下面

Protocol Buffer技术详解(C++实例)

http://www.cnblogs.com/stephen-liu74/archive/2013/01/04/2842533.html 这篇Blog仍然是以Google的官方文档为主线,代码实例则完全取自于我们正在开发的一个Demo项目,通过前一段时间的尝试,感觉这种结合的方式比 较有利于培训和内部的技术交流.还是那句话,没有最好的,只有最适合的.我想写Blog也是这一道理吧,不同的技术主题可能需要采用不同的风格.好了,还 是让我们尽早切入主题吧.          一.生成目标语言代码.  

Linux磁盘阵列技术详解(三)--raid 5和raid 10的创建

先来看一下raid 5: ① 分区 ② 创建raid 5 mdadm -C -v /dev/md5 -l 5 -n 3 -x 1 /dev/sde{1,2,3,4} ③ 模拟磁盘故障 这里其实和raid 1中的磁盘故障处理方法一样 mdadm -f /dev/md5 /dev/sde2 再来查看一下/proc/mdstat中的内容: 哈哈,看到了吧!已经变了哦! 来吧,删除故障盘命令如下: OK,接下来我就教给大家如何停止阵列: 注意,别忘了生成配置文件. 停止阵列的命令为:mdadm -S /

Linux crontab命令详解与实例

内容有重复的,不过本着宁多勿少的原则就都看看吧,就当加深印象啦 基本格式 :* * * * * command分 时 日 月 周 命令 第1列表示分钟1-59 每分钟用*或者 */1表示第2列表示小时1-23(0表示0点)第3列表示日期1-31第4列表示月份1-12第5列标识号星期0-6(0表示星期天)第6列要运行的命令 crontab文件的一些例子: 30 21 * * * /usr/local/etc/rc.d/lighttpd restart上面的例子表示每晚的21:30重启apache.

linux wget 命令用法详解(附实例说明)

Linux wget是一个下载文件的工具,它用在命令行下.对于Linux用户是必不可少的工具,尤其对于网络管理员,经常要下载一些软件或从远程服务器恢复备份到本地服务器.如果我们使用虚拟主机,处理这样的事务我们只能先从远程服务器下载到我们电脑磁盘,然后再用ftp工具上传到服务器.这样既浪费时间又浪费精力,那不没办法的事.而到了Linux VPS,它则可以直接下载到服务器而不用经过上传这一步.wget工具体积小但功能完善,它支持断点下载功能,同时支持FTP和HTTP下载方式,支持代理服务器和设置起来