aboutsummaryrefslogtreecommitdiffstats
path: root/Documentation
diff options
context:
space:
mode:
authorAnanth N Mavinakayanahalli <ananth@in.ibm.com>2008-03-04 17:28:38 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-03-04 19:35:11 -0500
commit804defea1c020d5c52985685e56986f1a399acde (patch)
treedd91b81d272522ec8e5e482408734dd290fed152 /Documentation
parent9edddaa200df18e08fe0cf21036e8ae467b1363c (diff)
Kprobes: move kprobe examples to samples/
Move kprobes examples from Documentation/kprobes.txt to under samples/. Patch originally by Randy Dunlap. o Updated the patch to apply on 2.6.25-rc3 o Modified examples code to build on multiple architectures. Currently, the kprobe and jprobe examples code works for x86 and powerpc o Cleaned up unneeded #includes o Cleaned up Kconfig per Sam Ravnborg's suggestions to fix build break on archs that don't have kretprobes o Implemented suggestions by Mathieu Desnoyers on CONFIG_KRETPROBES o Included Andrew Morton's cleanup based on x86-git o Modified kretprobe_example to act as a arch-agnostic module to determine routine execution times: Use 'modprobe kretprobe_example func=<func_name>' to determine execution time of func_name in nanoseconds. Signed-off-by: Randy Dunlap <randy.dunlap@oracle.com> Signed-off-by: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Acked-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/kprobes.txt243
1 files changed, 5 insertions, 238 deletions
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt
index 83f515c2905a..be89f393274f 100644
--- a/Documentation/kprobes.txt
+++ b/Documentation/kprobes.txt
@@ -192,7 +192,8 @@ code mapping.
192The Kprobes API includes a "register" function and an "unregister" 192The Kprobes API includes a "register" function and an "unregister"
193function for each type of probe. Here are terse, mini-man-page 193function for each type of probe. Here are terse, mini-man-page
194specifications for these functions and the associated probe handlers 194specifications for these functions and the associated probe handlers
195that you'll write. See the latter half of this document for examples. 195that you'll write. See the files in the samples/kprobes/ sub-directory
196for examples.
196 197
1974.1 register_kprobe 1984.1 register_kprobe
198 199
@@ -420,249 +421,15 @@ e. Watchpoint probes (which fire on data references).
420 421
4218. Kprobes Example 4228. Kprobes Example
422 423
423Here's a sample kernel module showing the use of kprobes to dump a 424See samples/kprobes/kprobe_example.c
424stack trace and selected i386 registers when do_fork() is called.
425----- cut here -----
426/*kprobe_example.c*/
427#include <linux/kernel.h>
428#include <linux/module.h>
429#include <linux/kprobes.h>
430#include <linux/sched.h>
431
432/*For each probe you need to allocate a kprobe structure*/
433static struct kprobe kp;
434
435/*kprobe pre_handler: called just before the probed instruction is executed*/
436int handler_pre(struct kprobe *p, struct pt_regs *regs)
437{
438 printk("pre_handler: p->addr=0x%p, eip=%lx, eflags=0x%lx\n",
439 p->addr, regs->eip, regs->eflags);
440 dump_stack();
441 return 0;
442}
443
444/*kprobe post_handler: called after the probed instruction is executed*/
445void handler_post(struct kprobe *p, struct pt_regs *regs, unsigned long flags)
446{
447 printk("post_handler: p->addr=0x%p, eflags=0x%lx\n",
448 p->addr, regs->eflags);
449}
450
451/* fault_handler: this is called if an exception is generated for any
452 * instruction within the pre- or post-handler, or when Kprobes
453 * single-steps the probed instruction.
454 */
455int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
456{
457 printk("fault_handler: p->addr=0x%p, trap #%dn",
458 p->addr, trapnr);
459 /* Return 0 because we don't handle the fault. */
460 return 0;
461}
462
463static int __init kprobe_init(void)
464{
465 int ret;
466 kp.pre_handler = handler_pre;
467 kp.post_handler = handler_post;
468 kp.fault_handler = handler_fault;
469 kp.symbol_name = "do_fork";
470
471 ret = register_kprobe(&kp);
472 if (ret < 0) {
473 printk("register_kprobe failed, returned %d\n", ret);
474 return ret;
475 }
476 printk("kprobe registered\n");
477 return 0;
478}
479
480static void __exit kprobe_exit(void)
481{
482 unregister_kprobe(&kp);
483 printk("kprobe unregistered\n");
484}
485
486module_init(kprobe_init)
487module_exit(kprobe_exit)
488MODULE_LICENSE("GPL");
489----- cut here -----
490
491You can build the kernel module, kprobe-example.ko, using the following
492Makefile:
493----- cut here -----
494obj-m := kprobe-example.o
495KDIR := /lib/modules/$(shell uname -r)/build
496PWD := $(shell pwd)
497default:
498 $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
499clean:
500 rm -f *.mod.c *.ko *.o
501----- cut here -----
502
503$ make
504$ su -
505...
506# insmod kprobe-example.ko
507
508You will see the trace data in /var/log/messages and on the console
509whenever do_fork() is invoked to create a new process.
510 425
5119. Jprobes Example 4269. Jprobes Example
512 427
513Here's a sample kernel module showing the use of jprobes to dump 428See samples/kprobes/jprobe_example.c
514the arguments of do_fork().
515----- cut here -----
516/*jprobe-example.c */
517#include <linux/kernel.h>
518#include <linux/module.h>
519#include <linux/fs.h>
520#include <linux/uio.h>
521#include <linux/kprobes.h>
522
523/*
524 * Jumper probe for do_fork.
525 * Mirror principle enables access to arguments of the probed routine
526 * from the probe handler.
527 */
528
529/* Proxy routine having the same arguments as actual do_fork() routine */
530long jdo_fork(unsigned long clone_flags, unsigned long stack_start,
531 struct pt_regs *regs, unsigned long stack_size,
532 int __user * parent_tidptr, int __user * child_tidptr)
533{
534 printk("jprobe: clone_flags=0x%lx, stack_size=0x%lx, regs=0x%p\n",
535 clone_flags, stack_size, regs);
536 /* Always end with a call to jprobe_return(). */
537 jprobe_return();
538 /*NOTREACHED*/
539 return 0;
540}
541
542static struct jprobe my_jprobe = {
543 .entry = jdo_fork
544};
545
546static int __init jprobe_init(void)
547{
548 int ret;
549 my_jprobe.kp.symbol_name = "do_fork";
550
551 if ((ret = register_jprobe(&my_jprobe)) <0) {
552 printk("register_jprobe failed, returned %d\n", ret);
553 return -1;
554 }
555 printk("Planted jprobe at %p, handler addr %p\n",
556 my_jprobe.kp.addr, my_jprobe.entry);
557 return 0;
558}
559
560static void __exit jprobe_exit(void)
561{
562 unregister_jprobe(&my_jprobe);
563 printk("jprobe unregistered\n");
564}
565
566module_init(jprobe_init)
567module_exit(jprobe_exit)
568MODULE_LICENSE("GPL");
569----- cut here -----
570
571Build and insert the kernel module as shown in the above kprobe
572example. You will see the trace data in /var/log/messages and on
573the console whenever do_fork() is invoked to create a new process.
574(Some messages may be suppressed if syslogd is configured to
575eliminate duplicate messages.)
576 429
57710. Kretprobes Example 43010. Kretprobes Example
578 431
579Here's a sample kernel module showing the use of return probes to 432See samples/kprobes/kretprobe_example.c
580report failed calls to sys_open().
581----- cut here -----
582/*kretprobe-example.c*/
583#include <linux/kernel.h>
584#include <linux/module.h>
585#include <linux/kprobes.h>
586#include <linux/ktime.h>
587
588/* per-instance private data */
589struct my_data {
590 ktime_t entry_stamp;
591};
592
593static const char *probed_func = "sys_open";
594
595/* Timestamp function entry. */
596static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
597{
598 struct my_data *data;
599
600 if(!current->mm)
601 return 1; /* skip kernel threads */
602
603 data = (struct my_data *)ri->data;
604 data->entry_stamp = ktime_get();
605 return 0;
606}
607
608/* If the probed function failed, log the return value and duration.
609 * Duration may turn out to be zero consistently, depending upon the
610 * granularity of time accounting on the platform. */
611static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
612{
613 int retval = regs_return_value(regs);
614 struct my_data *data = (struct my_data *)ri->data;
615 s64 delta;
616 ktime_t now;
617
618 if (retval < 0) {
619 now = ktime_get();
620 delta = ktime_to_ns(ktime_sub(now, data->entry_stamp));
621 printk("%s: return val = %d (duration = %lld ns)\n",
622 probed_func, retval, delta);
623 }
624 return 0;
625}
626
627static struct kretprobe my_kretprobe = {
628 .handler = return_handler,
629 .entry_handler = entry_handler,
630 .data_size = sizeof(struct my_data),
631 .maxactive = 20, /* probe up to 20 instances concurrently */
632};
633
634static int __init kretprobe_init(void)
635{
636 int ret;
637 my_kretprobe.kp.symbol_name = (char *)probed_func;
638
639 if ((ret = register_kretprobe(&my_kretprobe)) < 0) {
640 printk("register_kretprobe failed, returned %d\n", ret);
641 return -1;
642 }
643 printk("Kretprobe active on %s\n", my_kretprobe.kp.symbol_name);
644 return 0;
645}
646
647static void __exit kretprobe_exit(void)
648{
649 unregister_kretprobe(&my_kretprobe);
650 printk("kretprobe unregistered\n");
651 /* nmissed > 0 suggests that maxactive was set too low. */
652 printk("Missed probing %d instances of %s\n",
653 my_kretprobe.nmissed, probed_func);
654}
655
656module_init(kretprobe_init)
657module_exit(kretprobe_exit)
658MODULE_LICENSE("GPL");
659----- cut here -----
660
661Build and insert the kernel module as shown in the above kprobe
662example. You will see the trace data in /var/log/messages and on the
663console whenever sys_open() returns a negative value. (Some messages
664may be suppressed if syslogd is configured to eliminate duplicate
665messages.)
666 433
667For additional information on Kprobes, refer to the following URLs: 434For additional information on Kprobes, refer to the following URLs:
668http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe 435http://www-106.ibm.com/developerworks/library/l-kprobes.html?ca=dgr-lnxw42Kprobe