Skip to content

Commit

Permalink
Kprobes: print details of kretprobe on assertion failure
Browse files Browse the repository at this point in the history
In certain cases like when the real return address can't be found or when
the number of tracked calls to a kretprobed function is less than the
number of returns, we may not be able to find the correct return address
after processing a kretprobe.  Currently we just do a BUG_ON, but no
information is provided about the actual failing kretprobe.

Print out details of the kretprobe before calling BUG().

Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Prasanna S Panchamukhi <prasanna@in.ibm.com>
Cc: Jim Keniston <jkenisto@us.ibm.com>
Cc: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
Cc: Maneesh Soni <maneesh@in.ibm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Ananth N Mavinakayanahalli authored and Linus Torvalds committed May 8, 2007
1 parent 8f0c45c commit 0f95b7f
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 5 deletions.
3 changes: 1 addition & 2 deletions arch/i386/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -449,8 +449,7 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs)
break;
}

BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));

kretprobe_assert(ri, orig_ret_address, trampoline_address);
spin_unlock_irqrestore(&kretprobe_lock, flags);

hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) {
Expand Down
3 changes: 2 additions & 1 deletion arch/ia64/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,8 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
break;
}

BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
kretprobe_assert(ri, orig_ret_address, trampoline_address);

regs->cr_iip = orig_ret_address;

reset_current_kprobe();
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
break;
}

BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
kretprobe_assert(ri, orig_ret_address, trampoline_address);
regs->nip = orig_ret_address;

reset_current_kprobe();
Expand Down
2 changes: 1 addition & 1 deletion arch/x86_64/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
break;
}

BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address));
kretprobe_assert(ri, orig_ret_address, trampoline_address);
regs->rip = orig_ret_address;

reset_current_kprobe();
Expand Down
10 changes: 10 additions & 0 deletions include/linux/kprobes.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,16 @@ struct kretprobe_instance {
struct task_struct *task;
};

static inline void kretprobe_assert(struct kretprobe_instance *ri,
unsigned long orig_ret_address, unsigned long trampoline_address)
{
if (!orig_ret_address || (orig_ret_address == trampoline_address)) {
printk("kretprobe BUG!: Processing kretprobe %p @ %p\n",
ri->rp, ri->rp->kp.addr);
BUG();
}
}

extern spinlock_t kretprobe_lock;
extern struct mutex kprobe_mutex;
extern int arch_prepare_kprobe(struct kprobe *p);
Expand Down

0 comments on commit 0f95b7f

Please sign in to comment.