aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Weisbecker <fweisbec@gmail.com>2009-08-26 17:38:30 -0400
committerFrederic Weisbecker <fweisbec@gmail.com>2009-08-26 20:33:03 -0400
commit24851d2447830e6cba4c4b641cb73e713f312373 (patch)
treeb0aa315fc67b3aedab3bd84ef99ea3d933fd365c
parent30a7e073b590ebd1829a906164b0a637e77cc967 (diff)
tracing/kprobes: Dump the culprit kprobe in case of kprobe recursion
Kprobes can enter into a probing recursion, ie: a kprobe that does an endless loop because one of its core mechanism function used during probing is also probed itself. This patch helps pinpointing the kprobe that raised such recursion by dumping it and raising a BUG instead of a warning (we also disarm the kprobe to try avoiding recursion in BUG itself). Having a BUG instead of a warning stops the stacktrace in the right place and doesn't pollute the logs with hundreds of traces that eventually end up in a stack overflow. Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: Masami Hiramatsu <mhiramat@redhat.com> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
-rw-r--r--arch/x86/kernel/kprobes.c8
-rw-r--r--include/linux/kprobes.h2
-rw-r--r--kernel/kprobes.c7
3 files changed, 15 insertions, 2 deletions
diff --git a/arch/x86/kernel/kprobes.c b/arch/x86/kernel/kprobes.c
index 16ae9610f6ff..ecee3d23fef8 100644
--- a/arch/x86/kernel/kprobes.c
+++ b/arch/x86/kernel/kprobes.c
@@ -490,9 +490,13 @@ static int __kprobes reenter_kprobe(struct kprobe *p, struct pt_regs *regs,
490 /* A probe has been hit in the codepath leading up 490 /* A probe has been hit in the codepath leading up
491 * to, or just after, single-stepping of a probed 491 * to, or just after, single-stepping of a probed
492 * instruction. This entire codepath should strictly 492 * instruction. This entire codepath should strictly
493 * reside in .kprobes.text section. Raise a warning 493 * reside in .kprobes.text section.
494 * to highlight this peculiar case. 494 * Raise a BUG or we'll continue in an endless
495 * reentering loop and eventually a stack overflow.
495 */ 496 */
497 arch_disarm_kprobe(p);
498 dump_kprobe(p);
499 BUG();
496 } 500 }
497 default: 501 default:
498 /* impossible cases */ 502 /* impossible cases */
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index bcd9c07848be..87eb79c9dd60 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -296,6 +296,8 @@ void recycle_rp_inst(struct kretprobe_instance *ri, struct hlist_head *head);
296int disable_kprobe(struct kprobe *kp); 296int disable_kprobe(struct kprobe *kp);
297int enable_kprobe(struct kprobe *kp); 297int enable_kprobe(struct kprobe *kp);
298 298
299void dump_kprobe(struct kprobe *kp);
300
299#else /* !CONFIG_KPROBES: */ 301#else /* !CONFIG_KPROBES: */
300 302
301static inline int kprobes_built_in(void) 303static inline int kprobes_built_in(void)
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index ef177d653b2c..f72e96c25a38 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1141,6 +1141,13 @@ static void __kprobes kill_kprobe(struct kprobe *p)
1141 arch_remove_kprobe(p); 1141 arch_remove_kprobe(p);
1142} 1142}
1143 1143
1144void __kprobes dump_kprobe(struct kprobe *kp)
1145{
1146 printk(KERN_WARNING "Dumping kprobe:\n");
1147 printk(KERN_WARNING "Name: %s\nAddress: %p\nOffset: %x\n",
1148 kp->symbol_name, kp->addr, kp->offset);
1149}
1150
1144/* Module notifier call back, checking kprobes on the module */ 1151/* Module notifier call back, checking kprobes on the module */
1145static int __kprobes kprobes_module_callback(struct notifier_block *nb, 1152static int __kprobes kprobes_module_callback(struct notifier_block *nb,
1146 unsigned long val, void *data) 1153 unsigned long val, void *data)