2008-03-05 01:28:38 +03:00
/*
* NOTE : This example is works on x86 and powerpc .
* Here ' s a sample kernel module showing the use of kprobes to dump a
* stack trace and selected registers when do_fork ( ) is called .
*
* For more information on theory of operation of kprobes , see
* Documentation / kprobes . txt
*
* You will see the trace data in / var / log / messages and on the console
* whenever do_fork ( ) is invoked to create a new process .
*/
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/kprobes.h>
/* For each probe you need to allocate a kprobe structure */
static struct kprobe kp = {
. symbol_name = " do_fork " ,
} ;
/* kprobe pre_handler: called just before the probed instruction is executed */
static int handler_pre ( struct kprobe * p , struct pt_regs * regs )
{
# ifdef CONFIG_X86
printk ( KERN_INFO " pre_handler: p->addr = 0x%p, ip = %lx, "
" flags = 0x%lx \n " ,
p - > addr , regs - > ip , regs - > flags ) ;
# endif
# ifdef CONFIG_PPC
printk ( KERN_INFO " pre_handler: p->addr = 0x%p, nip = 0x%lx, "
" msr = 0x%lx \n " ,
p - > addr , regs - > nip , regs - > msr ) ;
# endif
2010-08-03 22:22:21 +04:00
# ifdef CONFIG_MIPS
printk ( KERN_INFO " pre_handler: p->addr = 0x%p, epc = 0x%lx, "
" status = 0x%lx \n " ,
p - > addr , regs - > cp0_epc , regs - > cp0_status ) ;
# endif
2008-03-05 01:28:38 +03:00
/* A dump_stack() here will give a stack backtrace */
return 0 ;
}
/* kprobe post_handler: called after the probed instruction is executed */
static void handler_post ( struct kprobe * p , struct pt_regs * regs ,
unsigned long flags )
{
# ifdef CONFIG_X86
printk ( KERN_INFO " post_handler: p->addr = 0x%p, flags = 0x%lx \n " ,
p - > addr , regs - > flags ) ;
# endif
# ifdef CONFIG_PPC
printk ( KERN_INFO " post_handler: p->addr = 0x%p, msr = 0x%lx \n " ,
p - > addr , regs - > msr ) ;
# endif
2010-08-03 22:22:21 +04:00
# ifdef CONFIG_MIPS
printk ( KERN_INFO " post_handler: p->addr = 0x%p, status = 0x%lx \n " ,
p - > addr , regs - > cp0_status ) ;
# endif
2008-03-05 01:28:38 +03:00
}
/*
* fault_handler : this is called if an exception is generated for any
* instruction within the pre - or post - handler , or when Kprobes
* single - steps the probed instruction .
*/
static int handler_fault ( struct kprobe * p , struct pt_regs * regs , int trapnr )
{
printk ( KERN_INFO " fault_handler: p->addr = 0x%p, trap #%dn " ,
p - > addr , trapnr ) ;
/* Return 0 because we don't handle the fault. */
return 0 ;
}
static int __init kprobe_init ( void )
{
int ret ;
kp . pre_handler = handler_pre ;
kp . post_handler = handler_post ;
kp . fault_handler = handler_fault ;
ret = register_kprobe ( & kp ) ;
if ( ret < 0 ) {
printk ( KERN_INFO " register_kprobe failed, returned %d \n " , ret ) ;
return ret ;
}
printk ( KERN_INFO " Planted kprobe at %p \n " , kp . addr ) ;
return 0 ;
}
static void __exit kprobe_exit ( void )
{
unregister_kprobe ( & kp ) ;
printk ( KERN_INFO " kprobe at %p unregistered \n " , kp . addr ) ;
}
module_init ( kprobe_init )
module_exit ( kprobe_exit )
MODULE_LICENSE ( " GPL " ) ;