2008-03-04 14:28:38 -08:00
/*
* NOTE : This example is works on x86 and powerpc .
* Here ' s a sample kernel module showing the use of kprobes to dump a
2015-10-01 15:37:11 -07:00
* stack trace and selected registers when _do_fork ( ) is called .
2008-03-04 14:28:38 -08:00
*
* 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
2015-10-01 15:37:11 -07:00
* whenever _do_fork ( ) is invoked to create a new process .
2008-03-04 14:28:38 -08:00
*/
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/kprobes.h>
2016-05-20 17:04:33 -07:00
# define MAX_SYMBOL_LEN 64
static char symbol [ MAX_SYMBOL_LEN ] = " _do_fork " ;
module_param_string ( symbol , symbol , sizeof ( symbol ) , 0644 ) ;
2008-03-04 14:28:38 -08:00
/* For each probe you need to allocate a kprobe structure */
static struct kprobe kp = {
2016-05-20 17:04:33 -07:00
. symbol_name = symbol ,
2008-03-04 14:28:38 -08:00
} ;
/* 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
2016-08-03 13:46:03 -07:00
pr_info ( " <%s> pre_handler: p->addr = 0x%p, ip = %lx, flags = 0x%lx \n " ,
2016-05-20 17:04:36 -07:00
p - > symbol_name , p - > addr , regs - > ip , regs - > flags ) ;
2008-03-04 14:28:38 -08:00
# endif
# ifdef CONFIG_PPC
2016-08-03 13:46:03 -07:00
pr_info ( " <%s> pre_handler: p->addr = 0x%p, nip = 0x%lx, msr = 0x%lx \n " ,
2016-05-20 17:04:36 -07:00
p - > symbol_name , p - > addr , regs - > nip , regs - > msr ) ;
2008-03-04 14:28:38 -08:00
# endif
2010-08-03 11:22:21 -07:00
# ifdef CONFIG_MIPS
2016-08-03 13:46:03 -07:00
pr_info ( " <%s> pre_handler: p->addr = 0x%p, epc = 0x%lx, status = 0x%lx \n " ,
2016-05-20 17:04:36 -07:00
p - > symbol_name , p - > addr , regs - > cp0_epc , regs - > cp0_status ) ;
2010-08-03 11:22:21 -07:00
# endif
2013-08-09 15:08:57 -04:00
# ifdef CONFIG_TILEGX
2016-08-03 13:46:03 -07:00
pr_info ( " <%s> pre_handler: p->addr = 0x%p, pc = 0x%lx, ex1 = 0x%lx \n " ,
2016-05-20 17:04:36 -07:00
p - > symbol_name , p - > addr , regs - > pc , regs - > ex1 ) ;
2013-08-09 15:08:57 -04:00
# endif
2016-07-08 12:35:54 -04:00
# ifdef CONFIG_ARM64
pr_info ( " <%s> pre_handler: p->addr = 0x%p, pc = 0x%lx, "
" pstate = 0x%lx \n " ,
p - > symbol_name , p - > addr , ( long ) regs - > pc , ( long ) regs - > pstate ) ;
# endif
2008-03-04 14:28:38 -08: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
2016-08-03 13:46:03 -07:00
pr_info ( " <%s> post_handler: p->addr = 0x%p, flags = 0x%lx \n " ,
2016-05-20 17:04:36 -07:00
p - > symbol_name , p - > addr , regs - > flags ) ;
2008-03-04 14:28:38 -08:00
# endif
# ifdef CONFIG_PPC
2016-08-03 13:46:03 -07:00
pr_info ( " <%s> post_handler: p->addr = 0x%p, msr = 0x%lx \n " ,
2016-05-20 17:04:36 -07:00
p - > symbol_name , p - > addr , regs - > msr ) ;
2008-03-04 14:28:38 -08:00
# endif
2010-08-03 11:22:21 -07:00
# ifdef CONFIG_MIPS
2016-08-03 13:46:03 -07:00
pr_info ( " <%s> post_handler: p->addr = 0x%p, status = 0x%lx \n " ,
2016-05-20 17:04:36 -07:00
p - > symbol_name , p - > addr , regs - > cp0_status ) ;
2010-08-03 11:22:21 -07:00
# endif
2013-08-09 15:08:57 -04:00
# ifdef CONFIG_TILEGX
2016-08-03 13:46:03 -07:00
pr_info ( " <%s> post_handler: p->addr = 0x%p, ex1 = 0x%lx \n " ,
2016-05-20 17:04:36 -07:00
p - > symbol_name , p - > addr , regs - > ex1 ) ;
2013-08-09 15:08:57 -04:00
# endif
2016-07-08 12:35:54 -04:00
# ifdef CONFIG_ARM64
pr_info ( " <%s> post_handler: p->addr = 0x%p, pstate = 0x%lx \n " ,
p - > symbol_name , p - > addr , ( long ) regs - > pstate ) ;
# endif
2008-03-04 14:28:38 -08: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 )
{
2016-08-03 13:46:03 -07:00
pr_info ( " fault_handler: p->addr = 0x%p, trap #%dn " , p - > addr , trapnr ) ;
2008-03-04 14:28:38 -08:00
/* 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 ) {
2016-08-03 13:46:03 -07:00
pr_err ( " register_kprobe failed, returned %d \n " , ret ) ;
2008-03-04 14:28:38 -08:00
return ret ;
}
2016-08-03 13:46:03 -07:00
pr_info ( " Planted kprobe at %p \n " , kp . addr ) ;
2008-03-04 14:28:38 -08:00
return 0 ;
}
static void __exit kprobe_exit ( void )
{
unregister_kprobe ( & kp ) ;
2016-08-03 13:46:03 -07:00
pr_info ( " kprobe at %p unregistered \n " , kp . addr ) ;
2008-03-04 14:28:38 -08:00
}
module_init ( kprobe_init )
module_exit ( kprobe_exit )
MODULE_LICENSE ( " GPL " ) ;