This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
Re: ia64 kprobes on syscalls
- From: Ananth N Mavinakayanahalli <ananth at in dot ibm dot com>
- To: Jes Sorensen <jes at trained-monkey dot org>
- Cc: systemtap at sourceware dot org
- Date: Fri, 24 Feb 2006 16:20:31 +0530
- Subject: Re: ia64 kprobes on syscalls
- References: <17406.55271.259820.993216@jaguar.mkp.net>
- Reply-to: ananth at in dot ibm dot com
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");