Windows XP Windows 7 Windows 2003 Windows Vista Windows教程綜合 Linux 系統教程
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟件教程
 Windows教程網 >> Linux系統教程 >> Linux教程 >> 紅帽Linux上的故障定位技術

紅帽Linux上的故障定位技術

日期:2017/2/7 9:23:34      編輯:Linux教程

kprobe是SystemTap對內核函數進行probing的功能在內核中的實現,由於內核中提供了正式的API來使用kprobe,所以對很多內核程序員來說,也許直接使用kprobe比使用SystemTap更方便. 內核中提供了三種類型的kprobe處理函數,分別是jprobe, kprobe, kretprobe, 下面的代碼用這三個probe觀察在TCP/IP的arp_process函數執行中對ip_route_input()調用的返回結果.這個代碼還展示了在同一個函數probe的Entry handler和Ret handler之間共享參數的方法. 代碼如下:

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

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

MODULE_AUTHOR("[email protected]");
MODULE_DESCRIPTION("A module to track the call results of ip_route_input() inside arp_process using jprobe and kretprobe");
MODULE_LICENSE("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("\narp_process() is called with interface device %s, in_dev(no_addr=%d,rpf=%d) \n", 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 \n", 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 kretprobe_instance *ri, struct pt_regs *regs)
{
printk("Calling: %s()\n", 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)\n", 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()\n", 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\n", 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\n", RTN_UNICAST);
if ( (ret = register_jprobe(&my_jp1)) < 0) {
printk("register_jprobe %s failed, returned %d\n", my_jp1.kp.symbol_name, ret);
return(-1);
}

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

if ( (ret = register_kretprobe(&my_rp1)) < 0 ) {
printk("register_kretprobe %s failed, returned %d\n", 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\n", 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\n", 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教程網 All Rights Reserved