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]

ia64 kprobes on syscalls


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?

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];
+
+			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]