Fault location on Linux

  

Use kprobe to observe the execution of a kernel function. Power failure linux installation kprobe is a function of systemTap probing of kernel functions in the kernel. Since the kernel provides a formal API to use kprobe, it is a lot of kernel programmers. For example, it may be more convenient to use kprobe directly than using SystemTap. There are three types of kprobe handlers in the kernel, namely jprobe, kprobe, kretprobe. The following code uses these three probes to observe the execution of the arp_process function in TCP/IP. The result of the call to ip_route_input(). This code also shows the method of sharing parameters between the Entry handler and the Ret handler of the same function probe. The code is as follows: windows7 fault

arp_probe.c /* * Arp_probe.c, by Qianfeng Zhang ([email protected]) */

#include #include #include #include #include #include #include #include

MODULE_AUTHOR("frzhang@ Redhat.com"); MODULE_DESCRIPTION("A module to track the call results of ip_route_input() inside arp_process using jprobe and kretprobe"); MODULE_LICENS E("GPL");

static int j_arp_process(struct sk_buff *skb) { struct net_device *dev = skb->dev; struct in_device *in_dev; int no_addr, rpf;

in_dev = in_dev_get(dev); no_addr = ( in_dev->ifa_list == NULL ); rpf = IN_DEV_RPFILTER(in_dev); in_dev_put(in_dev); printk("\ arp_process() is called with interface device %s, in_dev (no_addr=%d,rpf=%d) \ ", dev->name, no_addr, rpf); jprobe_return(); return(0); };

static int j_fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, struct net_device *dev, __be32 *spec_dst, u32 *itag, u32 mark)

{ printk("fib_validate_source() is called with dst=0x%x, oif= %d \ ", dst, oif); jprobe_return(); return(0); };

static struct jprobe my_jp1 = { .entry = j_arp_process, .kp.symbol_name = "arp_process" };


static struct jprobe my_jp2 = { .entry = j_fib_validate_source, .kp.symbol_name = "fib_validate_source" };

static int entry_handler(struct kre Tprobe_instance *ri, struct pt_regs *regs) { printk("Calling: %s()\ ", ri->rp->kp.symbol_name); return(0); };

Static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs) { int eax;

eax = regs->ax & 0xffff ; printk("Returning: %s() with a return value: 0x%lx(64bit) 0x%x(32bit)\ ", ri->rp->kp.symbol_name, regs->ax, eax);

return(0); };

static int fib_lookup_entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs) { struct fib_result *resp;

resp = (struct fib_result *) regs->dx; printk("Calling : %s()\ ", ri->rp->kp.symbol_name); *((struct fib_result **)ri->data) = resp;

return(0); };


static int fib_lookup_return_handler(struct kretprobe_instance *ri, struct pt_regs *regs) { struct fib_result *resp; int eax;

eax = regs->ax & 0xffff ; resp = *((struct fib_result **) ri->data); printk("Returning: fib_lookup() with a return Value: 0x%lx(64bit) 0x%x(32bit), result->type: %d\ ", regs->ax, eax, resp->type);

return( 0); }

static struct kretprobe my_rp1 = { .handler = return_handler, .entry_handler = entry_handler, .kp.symbol_name = "ip_route_input_slow" };


static Struct kretprobe my_rp2 = { .handler = return_handler, .entry_handler = entry_handler, .kp.symbol_name = "fib_validate_source" };


static struct kretprobe my_rp3 = { .handler = fib_lookup_return_handler, . Entry_handler = fib_lookup_entry_handler, .kp.symbol_name = "fib_lookup", .data_size = sizeof(struct fib_result *) };

static int __init init_myprobe(void) { int ret;

printk( "RTN_UNICAST is %d\ ", RTN_UNICAST); if ( (ret = register_jprobe(&my_jp1)) < 0) { printk("register_jprobe %s failed, returned %d\ ", my_jp1.kp. Symbol_name, ret); return(-1); }

if ( (ret = register_jprobe(&my_jp2)) < 0) { printk("regi Ster_jprobe %s failed, returned %d\ ", my_jp2.kp.symbol_name, ret); return(-1); }

if ( (ret = register_kretprobe(&my_rp1)) < 0 ) { printk("register_kretprobe %s failed, returned %d\ ", my_rp1.kp.symbol_name, ret); unregister_jprobe(&my_jp1); unregister_jprobe(&my_jp2); return(-1); }

if ( (ret = register_kretprobe(&my_rp2)) < 0 ) { printk("register_kretprobe %s failed, returned %d\ ", my_rp2.kp.symbol_name, ret); unregister_jprobe(&my_jp1 ); unregister_jprobe(&my_jp2); unregister_kretprobe(&my_rp1); return(-1); }

if ( (ret = register_kretprobe(&my_rp3)) < 0 ) { printk(" Register_kretprobe %s failed, returned %d\ ", my_rp3.kp.symbol_name, ret); unregister_jprobe(&my_jp1); unregister_jprobe(&my_jp2); unregister_kretprobe(&my_rp1); unregister_kretprobe(&my_rp2); return (-1); }

return 0; }

Copyright © Windows knowledge All Rights Reserved