[patch 3/3] Trace sample - Kernel

This is a discussion on [patch 3/3] Trace sample - Kernel ; Trace example - Adds the trace example to samples/ Signed-off-by: David Wilder --- samples/Kconfig | 6 ++ samples/Makefile | 1 + samples/trace/Makefile | 4 + samples/trace/fork_trace.c | 132 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 143 insertions(+), 0 deletions(-) diff --git a/samples/Kconfig b/samples/Kconfig ...

+ Reply to Thread
Results 1 to 2 of 2

Thread: [patch 3/3] Trace sample

  1. [patch 3/3] Trace sample

    Trace example - Adds the trace example to samples/

    Signed-off-by: David Wilder
    ---
    samples/Kconfig | 6 ++
    samples/Makefile | 1 +
    samples/trace/Makefile | 4 +
    samples/trace/fork_trace.c | 132 ++++++++++++++++++++++++++++++++++++++++++++
    4 files changed, 143 insertions(+), 0 deletions(-)

    diff --git a/samples/Kconfig b/samples/Kconfig
    index 57bb223..e11c806 100644
    --- a/samples/Kconfig
    +++ b/samples/Kconfig
    @@ -13,4 +13,10 @@ config SAMPLE_MARKERS
    help
    This build markers example modules.

    +config SAMPLE_TRACE
    + tristate "Build trace example -- loadable modules only"
    + depends on TRACE && m
    + help
    + This builds a trace example module.
    +
    endif # SAMPLES
    diff --git a/samples/Makefile b/samples/Makefile
    index 5a4f0b6..8f6d05b 100644
    --- a/samples/Makefile
    +++ b/samples/Makefile
    @@ -1,3 +1,4 @@
    # Makefile for Linux samples code

    obj-$(CONFIG_SAMPLES) += markers/
    +obj-$(CONFIG_SAMPLES) += trace/
    diff --git a/samples/trace/Makefile b/samples/trace/Makefile
    new file mode 100644
    index 0000000..a2da8af
    --- /dev/null
    +++ b/samples/trace/Makefile
    @@ -0,0 +1,4 @@
    +# builds the trace example kernel modules;
    +# then to use (as root): insmod
    +
    +obj-$(CONFIG_SAMPLE_TRACE) := fork_trace.o
    diff --git a/samples/trace/fork_trace.c b/samples/trace/fork_trace.c
    new file mode 100644
    index 0000000..71c04c7
    --- /dev/null
    +++ b/samples/trace/fork_trace.c
    @@ -0,0 +1,132 @@
    +/*
    + * An example of using trace in a kprobes module
    + *
    + * Copyright (C) 2007 IBM Inc.
    + *
    + * David Wilder
    + *
    + * This program is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License version 2 as
    + * published by the Free Software Foundation.
    + *
    + * This program is distributed in the hope that it will be useful,
    + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    + * GNU General Public License for more details.
    + *
    + * You should have received a copy of the GNU General Public License
    + * along with this program; if not, write to the Free Software
    + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    + *
    + * -------
    + * This module creates a trace channel and places a kprobe
    + * on the function do_fork(). The value of current->pid is written to
    + * the trace channel each time the kprobe is hit..
    + *
    + * How to run the example:
    + * $ mount -t debugfs /debug
    + * $ insmod fork_trace.ko
    + *
    + * To view the data produced by the module:
    + * $ cat /debug/trace_example/do_fork/trace0
    + *
    + */
    +
    +#include
    +#include
    +#include
    +#include
    +
    +#define USE_GLOBAL_BUFFERS 1
    +#define USE_FLIGHT 1
    +
    +#define PROBE_POINT "do_fork"
    +
    +static struct kprobe kp;
    +static struct trace_info *kprobes_trace;
    +
    +#ifdef USE_GLOBAL_BUFFERS
    +static DEFINE_SPINLOCK(trace_lock);
    +#endif
    +
    +/*
    + * Send formatted trace data to trace channel.
    + * @note Preemption must be disabled to use this.
    + */
    +static void trace_printf(struct trace_info *trace, const char *format, ...)
    +{
    + va_list ap, aq;
    + char *record;
    + unsigned long flags;
    + int len;
    +
    + if (!trace)
    + return;
    +
    +#ifdef USE_GLOBAL_BUFFERS
    + spin_lock_irqsave(&trace_lock, flags);
    +#endif
    + if (trace_running(trace)) {
    + va_start(ap, format);
    + va_copy(aq, ap);
    + len = vsnprintf(NULL, 0, format, aq);
    + va_end(aq);
    + record = relay_reserve(trace->rchan, ++len);
    + if (record)
    + vsnprintf(record, len, format, ap);
    + va_end(ap);
    + }
    +#ifdef USE_GLOBAL_BUFFERS
    + spin_unlock_irqrestore(&trace_lock, flags);
    +#endif
    +}
    +
    +static int handler_pre(struct kprobe *p, struct pt_regs *regs)
    +{
    + rcu_read_lock();
    + trace_printf(kprobes_trace, "%d\n", current->pid);
    + rcu_read_unlock();
    + return 0;
    +}
    +
    +int init_module(void)
    +{
    + int ret;
    + u32 flags = 0;
    +
    +#ifdef USE_GLOBAL_BUFFERS
    + flags |= TRACE_GLOBAL_CHANNEL;
    +#endif
    +
    +#ifdef USE_FLIGHT
    + flags |= TRACE_FLIGHT_CHANNEL;
    +#endif
    +
    + /* setup the trace */
    + kprobes_trace = trace_setup("trace_example", PROBE_POINT,
    + 1024, 8, flags);
    + if (IS_ERR(kprobes_trace))
    + return PTR_ERR(kprobes_trace);
    +
    + trace_start(kprobes_trace);
    +
    + /* setup the kprobe */
    + kp.pre_handler = handler_pre;
    + kp.post_handler = NULL;
    + kp.fault_handler = NULL;
    + kp.symbol_name = PROBE_POINT;
    + ret = register_kprobe(&kp);
    + if (ret) {
    + printk(KERN_ERR "fork_trace: register_kprobe failed\n");
    + return ret;
    + }
    + return 0;
    +}
    +
    +void cleanup_module(void)
    +{
    + unregister_kprobe(&kp);
    + trace_stop(kprobes_trace);
    + trace_cleanup(kprobes_trace);
    +}
    +MODULE_LICENSE("GPL");


    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  2. Re: [patch 3/3] Trace sample

    On Wed, 26 Sep 2007 11:22:43 -0700 David J. Wilder wrote:

    > Trace example - Adds the trace example to samples/
    >
    > Signed-off-by: David Wilder


    Acked-by: Randy Dunlap


    > ---
    > samples/Kconfig | 6 ++
    > samples/Makefile | 1 +
    > samples/trace/Makefile | 4 +
    > samples/trace/fork_trace.c | 132 ++++++++++++++++++++++++++++++++++++++++++++
    > 4 files changed, 143 insertions(+), 0 deletions(-)
    >
    > diff --git a/samples/Kconfig b/samples/Kconfig
    > index 57bb223..e11c806 100644
    > --- a/samples/Kconfig
    > +++ b/samples/Kconfig
    > @@ -13,4 +13,10 @@ config SAMPLE_MARKERS
    > help
    > This build markers example modules.
    >
    > +config SAMPLE_TRACE
    > + tristate "Build trace example -- loadable modules only"
    > + depends on TRACE && m
    > + help
    > + This builds a trace example module.
    > +
    > endif # SAMPLES
    > diff --git a/samples/Makefile b/samples/Makefile
    > index 5a4f0b6..8f6d05b 100644
    > --- a/samples/Makefile
    > +++ b/samples/Makefile
    > @@ -1,3 +1,4 @@
    > # Makefile for Linux samples code
    >
    > obj-$(CONFIG_SAMPLES) += markers/
    > +obj-$(CONFIG_SAMPLES) += trace/
    > diff --git a/samples/trace/Makefile b/samples/trace/Makefile
    > new file mode 100644
    > index 0000000..a2da8af
    > --- /dev/null
    > +++ b/samples/trace/Makefile
    > @@ -0,0 +1,4 @@
    > +# builds the trace example kernel modules;
    > +# then to use (as root): insmod
    > +
    > +obj-$(CONFIG_SAMPLE_TRACE) := fork_trace.o
    > diff --git a/samples/trace/fork_trace.c b/samples/trace/fork_trace.c
    > new file mode 100644
    > index 0000000..71c04c7
    > --- /dev/null
    > +++ b/samples/trace/fork_trace.c
    > @@ -0,0 +1,132 @@
    > +/*
    > + * An example of using trace in a kprobes module
    > + *
    > + * Copyright (C) 2007 IBM Inc.
    > + *
    > + * David Wilder
    > + *
    > + * This program is free software; you can redistribute it and/or modify
    > + * it under the terms of the GNU General Public License version 2 as
    > + * published by the Free Software Foundation.
    > + *
    > + * This program is distributed in the hope that it will be useful,
    > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    > + * GNU General Public License for more details.
    > + *
    > + * You should have received a copy of the GNU General Public License
    > + * along with this program; if not, write to the Free Software
    > + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
    > + *
    > + * -------
    > + * This module creates a trace channel and places a kprobe
    > + * on the function do_fork(). The value of current->pid is written to
    > + * the trace channel each time the kprobe is hit..
    > + *
    > + * How to run the example:
    > + * $ mount -t debugfs /debug
    > + * $ insmod fork_trace.ko
    > + *
    > + * To view the data produced by the module:
    > + * $ cat /debug/trace_example/do_fork/trace0
    > + *
    > + */
    > +
    > +#include
    > +#include
    > +#include
    > +#include
    > +
    > +#define USE_GLOBAL_BUFFERS 1
    > +#define USE_FLIGHT 1
    > +
    > +#define PROBE_POINT "do_fork"
    > +
    > +static struct kprobe kp;
    > +static struct trace_info *kprobes_trace;
    > +
    > +#ifdef USE_GLOBAL_BUFFERS
    > +static DEFINE_SPINLOCK(trace_lock);
    > +#endif
    > +
    > +/*
    > + * Send formatted trace data to trace channel.
    > + * @note Preemption must be disabled to use this.
    > + */
    > +static void trace_printf(struct trace_info *trace, const char *format, ...)
    > +{
    > + va_list ap, aq;
    > + char *record;
    > + unsigned long flags;
    > + int len;
    > +
    > + if (!trace)
    > + return;
    > +
    > +#ifdef USE_GLOBAL_BUFFERS
    > + spin_lock_irqsave(&trace_lock, flags);
    > +#endif
    > + if (trace_running(trace)) {
    > + va_start(ap, format);
    > + va_copy(aq, ap);
    > + len = vsnprintf(NULL, 0, format, aq);
    > + va_end(aq);
    > + record = relay_reserve(trace->rchan, ++len);
    > + if (record)
    > + vsnprintf(record, len, format, ap);
    > + va_end(ap);
    > + }
    > +#ifdef USE_GLOBAL_BUFFERS
    > + spin_unlock_irqrestore(&trace_lock, flags);
    > +#endif
    > +}
    > +
    > +static int handler_pre(struct kprobe *p, struct pt_regs *regs)
    > +{
    > + rcu_read_lock();
    > + trace_printf(kprobes_trace, "%d\n", current->pid);
    > + rcu_read_unlock();
    > + return 0;
    > +}
    > +
    > +int init_module(void)
    > +{
    > + int ret;
    > + u32 flags = 0;
    > +
    > +#ifdef USE_GLOBAL_BUFFERS
    > + flags |= TRACE_GLOBAL_CHANNEL;
    > +#endif
    > +
    > +#ifdef USE_FLIGHT
    > + flags |= TRACE_FLIGHT_CHANNEL;
    > +#endif
    > +
    > + /* setup the trace */
    > + kprobes_trace = trace_setup("trace_example", PROBE_POINT,
    > + 1024, 8, flags);
    > + if (IS_ERR(kprobes_trace))
    > + return PTR_ERR(kprobes_trace);
    > +
    > + trace_start(kprobes_trace);
    > +
    > + /* setup the kprobe */
    > + kp.pre_handler = handler_pre;
    > + kp.post_handler = NULL;
    > + kp.fault_handler = NULL;
    > + kp.symbol_name = PROBE_POINT;
    > + ret = register_kprobe(&kp);
    > + if (ret) {
    > + printk(KERN_ERR "fork_trace: register_kprobe failed\n");
    > + return ret;
    > + }
    > + return 0;
    > +}
    > +
    > +void cleanup_module(void)
    > +{
    > + unregister_kprobe(&kp);
    > + trace_stop(kprobes_trace);
    > + trace_cleanup(kprobes_trace);
    > +}
    > +MODULE_LICENSE("GPL");
    >
    >
    > -


    ---
    ~Randy
    Phaedrus says that Quality is about caring.
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

+ Reply to Thread