This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: ia64 kprobes on syscalls


On Fri, Feb 24, 2006 at 04:54:47AM -0500, Jes Sorensen wrote:
> Hi,
> 
> I am trying to use kprobes to monitor system calls on ia64. However I am
> not exactly having a lot of luck with it ;( I tried a couple of
> approaches so far and they all seem to result in the kernel exploding
> quickly.
> 
> First attempt was to add probes directly to the syscall entry code. Now
> I am trying to add it to the sys_foo functions instead by walking the
> sys_call_table, but it seems to have the same problem.
> 
> Has anyone done this successfully on ia64? Is it supposed to work? I was
> speaking to Suparna who said there were some systemtap scripts to do
> this, so I a presume it has at least been working at some point for the
> x86?

There is some work going on, on instrumenting syscalls using
systemtap, but AFAIK, the targets are currently i386 and x86_64 ...

http://sources.redhat.com/cgi-bin/cvsweb.cgi/~checkout~/src/tapset/syscalls.stp?rev=1.6&content-type=text/plain&cvsroot=systemtap

and

http://sources.redhat.com/cgi-bin/cvsweb.cgi/~checkout~/src/tapset/syscalls2.stp?rev=1.10&content-type=text/plain&cvsroot=systemtap

> I've attached a simple test case below if anyone wishes to comment upon
> it (or tell me why I am utterly stupid ;) Ignore the fact that this
> thing is leaking struct kprobe's left right and center.
> 
> Cheers,
> Jes
> 
> 
> Index: linux-2.6/arch/ia64/Kconfig.debug
> ===================================================================
> --- linux-2.6.orig/arch/ia64/Kconfig.debug
> +++ linux-2.6/arch/ia64/Kconfig.debug
> @@ -2,6 +2,9 @@
>  
>  source "lib/Kconfig.debug"
>  
> +config IA64_SYSCALL_PROBES
> +	tristate "Enable syscall probe hack"
> +
>  choice
>  	prompt "Physical memory granularity"
>  	default IA64_GRANULE_64MB
> Index: linux-2.6/arch/ia64/kernel/Makefile
> ===================================================================
> --- linux-2.6.orig/arch/ia64/kernel/Makefile
> +++ linux-2.6/arch/ia64/kernel/Makefile
> @@ -30,6 +30,7 @@
>  obj-$(CONFIG_KPROBES)		+= kprobes.o jprobes.o
>  obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR)	+= uncached.o
>  mca_recovery-y			+= mca_drv.o mca_drv_asm.o
> +obj-$(CONFIG_IA64_SYSCALL_PROBES)		+= syscall-probes.o
>  
>  # The gate DSO image is built using a special linker script.
>  targets += gate.so gate-syms.o
> Index: linux-2.6/arch/ia64/kernel/ia64_ksyms.c
> ===================================================================
> --- linux-2.6.orig/arch/ia64/kernel/ia64_ksyms.c
> +++ linux-2.6/arch/ia64/kernel/ia64_ksyms.c
> @@ -108,3 +108,6 @@
>  
>  extern char ia64_ivt[];
>  EXPORT_SYMBOL(ia64_ivt);
> +
> +extern unsigned long sys_call_table[];
> +EXPORT_SYMBOL(sys_call_table);
> Index: linux-2.6/arch/ia64/kernel/syscall-probes.c
> ===================================================================
> --- /dev/null
> +++ linux-2.6/arch/ia64/kernel/syscall-probes.c
> @@ -0,0 +1,88 @@
> +/*
> + * This file is subject to the terms and conditions of the GNU General Public
> + * License.  See the file "COPYING" in the main directory of this archive
> + * for more details.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/fs.h>
> +#include <linux/uio.h>
> +#include <linux/kprobes.h>
> +#include <linux/kallsyms.h>
> +#include <asm/unistd.h>
> +
> +static int count;
> +
> +
> +static int
> +syscall_enter_pre_handler(struct kprobe *probe, struct pt_regs *regs)
> +{
> +	if (count++ < 25)
> +		printk(KERN_DEBUG "syscall me harder! r15\n");
> +
> +	return 0;
> +}
> +
> +static int probe_fault_handler(struct kprobe *probe,
> +			       struct pt_regs *regs, int trap)
> +{
> +	printk(KERN_DEBUG "probe_fault_handler: addr %p, trap %i\n",
> +	       probe->addr, trap);
> +	return 0;
> +}
> +
> +extern unsigned long sys_call_table[];
> +
> +static int install_syscall_enter_probe(void)
> +{
> +	int ret, i, j;
> +	struct kprobe *p;
> +
> +	printk(KERN_DEBUG "installing syscall_enter probe!\n");
> +
> +	for (i = 1, j = 0; i < NR_syscalls; i++) {
> +		/*
> +		 * entry 0 is always a ni_syscall
> +		 */
> +		if (sys_call_table[i] != sys_call_table[0]) {
> +			p = kmalloc(sizeof(struct kprobe), GFP_KERNEL);
> +			BUG_ON(!p);
> +
> +			p->pre_handler = syscall_enter_pre_handler;
> +			p->fault_handler = probe_fault_handler;
> +			p->addr = (void *)sys_call_table[i];

(Disclaimer: I know nothing about IA64 :) Would changing the above to

			p->addr = (kprobe_opcode_t *)sys_call_table[i];

make any difference? kprobe_opcode_t on ia64 is a struct with one
element of type bundle_t (and I see bundle_t is a big struct in itself)

Ananth

> +
> +			ret = register_kprobe(p);
> +			if (ret)
> +				BUG();
> +			j++;
> +		}
> +	}
> +
> +
> +	printk(KERN_DEBUG "installed %i syscall probes\n", j);
> +	return ret;
> +}
> +
> +
> +static int init_syscall_probes(void)
> +{
> +	/* kprobes */
> +	install_syscall_enter_probe();
> +	return 0;
> +};
> +
> +static void exit_syscall_probes(void)
> +{
> +#if 0
> +	unregister_kprobe(&syscall_enter_probe);
> +	printk(KERN_DEBUG "syscall probe be gone!\n");
> +#endif
> +};
> +
> +
> +module_init(init_syscall_probes);
> +module_exit(exit_syscall_probes);
> +
> +MODULE_LICENSE("GPL");


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]