zoukankan      html  css  js  c++  java
  • 红帽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 (frzhang@redhat.com)  
    3. */  
    4.  
    5. #include   
    6. #include   
    7. #include   
    8. #include   
    9. #include   
    10. #include   
    11. #include   
    12. #include   
    13.  
    14. MODULE_AUTHOR("frzhang@redhat.com");  
    15. MODULE_DESCRIPTION("A module to track the call results of ip_route_input() inside arp_process using jprobe and kretprobe");  
    16. MODULE_LICENSE("GPL");  
    17.  
    18. static int j_arp_process(struct sk_buff *skb)  
    19. {  
    20. struct net_device *dev = skb->dev;  
    21. struct in_device *in_dev;  
    22. int no_addr, rpf;  
    23.  
    24. in_dev = in_dev_get(dev);  
    25. no_addr = ( in_dev->ifa_list == NULL );  
    26. rpf = IN_DEV_RPFILTER(in_dev);  
    27. in_dev_put(in_dev);  
    28. printk(" arp_process() is called with interface device %s, in_dev(no_addr=%d,rpf=%d)  ", dev->name, no_addr, rpf);  
    29. jprobe_return();  
    30. return(0);  
    31. };  
    32.  
    33. static int j_fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,  
    34. struct net_device *dev, __be32 *spec_dst, u32 *itag, u32 mark)  
    35.  
    36. {  
    37. printk("fib_validate_source() is called with dst=0x%x, oif=%d  ", dst, oif);  
    38. jprobe_return();  
    39. return(0);  
    40. };  
    41.  
    42. static struct jprobe my_jp1 = {  
    43. .entry = j_arp_process,  
    44. .kp.symbol_name = "arp_process" 
    45. };  
    46.  
    47. static struct jprobe my_jp2 = {  
    48. .entry = j_fib_validate_source,  
    49. .kp.symbol_name = "fib_validate_source" 
    50. };  
    51.  
    52. static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)  
    53. {  
    54. printk("Calling: %s() ", ri->rp->kp.symbol_name);  
    55. return(0);  
    56. };  
    57.  
    58. static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)  
    59. {  
    60. int eax;  
    61.  
    62. eax = regs->ax & 0xffff ;  
    63. printk("Returning: %s() with a return value: 0x%lx(64bit) 0x%x(32bit) ", ri->rp->kp.symbol_name, regs->ax, eax);  
    64.  
    65. return(0);  
    66. };  
    67.  
    68. static int fib_lookup_entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)  
    69. {  
    70. struct fib_result *resp;  
    71.  
    72. resp = (struct fib_result *) regs->dx;  
    73. printk("Calling: %s() ", ri->rp->kp.symbol_name);  
    74. *((struct fib_result **)ri->data) = resp;  
    75.  
    76. return(0);  
    77. };  
    78.  
    79. static int fib_lookup_return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)  
    80. {  
    81. struct fib_result *resp;  
    82. int eax;  
    83.  
    84. eax = regs->ax & 0xffff ;  
    85. resp = *((struct fib_result **) ri->data);  
    86. printk("Returning: fib_lookup() with a return value: 0x%lx(64bit) 0x%x(32bit), result->type: %d ", regs->ax, eax, resp->type);  
    87.  
    88. return(0);  
    89. }  
    90.  
    91. static struct kretprobe my_rp1 = {  
    92. .handler = return_handler,  
    93. .entry_handler = entry_handler,  
    94. .kp.symbol_name = "ip_route_input_slow" 
    95. };  
    96.  
    97. static struct kretprobe my_rp2 = {  
    98. .handler = return_handler,  
    99. .entry_handler = entry_handler,  
    100. .kp.symbol_name = "fib_validate_source" 
    101. };  
    102.  
    103. static struct kretprobe my_rp3 = {  
    104. .handler = fib_lookup_return_handler,  
    105. .entry_handler = fib_lookup_entry_handler,  
    106. .kp.symbol_name = "fib_lookup",  
    107. .data_size = sizeof(struct fib_result *)  
    108. };  
    109.  
    110. static int __init init_myprobe(void)  
    111. {  
    112. int ret;  
    113.  
    114. printk("RTN_UNICAST is %d ", RTN_UNICAST);  
    115. if ( (ret = register_jprobe(&my_jp1)) 0) {  
    116. printk("register_jprobe %s failed, returned %d ", my_jp1.kp.symbol_name, ret);  
    117. return(-1);  
    118. }  
    119.  
    120. if ( (ret = register_jprobe(&my_jp2)) 0) {  
    121. printk("register_jprobe %s failed, returned %d ", my_jp2.kp.symbol_name, ret);  
    122. return(-1);  
    123. }  
    124.  
    125. if ( (ret = register_kretprobe(&my_rp1)) 0 ) {  
    126. printk("register_kretprobe %s failed, returned %d ", my_rp1.kp.symbol_name, ret);  
    127. unregister_jprobe(&my_jp1);  
    128. unregister_jprobe(&my_jp2);  
    129. return(-1);  
    130. }  
    131.  
    132. if ( (ret = register_kretprobe(&my_rp2)) 0 ) {  
    133. printk("register_kretprobe %s failed, returned %d ", my_rp2.kp.symbol_name, ret);  
    134. unregister_jprobe(&my_jp1);  
    135. unregister_jprobe(&my_jp2);  
    136. unregister_kretprobe(&my_rp1);  
    137. return(-1);  
    138. }  
    139.  
    140. if ( (ret = register_kretprobe(&my_rp3)) 0 ) {  
    141. printk("register_kretprobe %s failed, returned %d ", my_rp3.kp.symbol_name, ret);  
    142. unregister_jprobe(&my_jp1);  
    143. unregister_jprobe(&my_jp2);  
    144. unregister_kretprobe(&my_rp1);  
    145. unregister_kretprobe(&my_rp2);  
    146. return(-1);  
    147. }  
    148.  
    149. return 0;  
    150. }  
    151.  
    152.  
    153. static void __exit rel_myprobe(void)  
    154. {  
    155. unregister_jprobe(&my_jp1);  
    156. unregister_jprobe(&my_jp2);  
    157. unregister_kretprobe(&my_rp1);  
    158. unregister_kretprobe(&my_rp2);  
    159. unregister_kretprobe(&my_rp3);  
    160. }  
    161.  
    162. module_init(init_myprobe);  
    163. module_exit(rel_myprobe);  
    164.  
    165. Makefile obj-m += arp_probe.o  
    166. 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

  • 相关阅读:
    String类
    Scanner类
    Object类
    接口
    static关键字
    final关键字
    抽象类
    权限修饰符
    方法重写 (Override)
    面向对象思想特征
  • 原文地址:https://www.cnblogs.com/L-H-R-X-hehe/p/3963501.html
Copyright © 2011-2022 走看看