diff --git a/README.md b/README.md index 44d4bc7b6b16..63cd5b58bfa9 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,9 @@ Tracing... Hit Ctrl-C to end. The above output shows a bimodal distribution, where the largest mode of 800 I/O was between 128 and 255 Kbytes in size. -See the source: [bitehist.c](examples/tracing/bitehist.c) and -[bitehist.py](examples/tracing/bitehist.py). What this traces, what this stores, and how -the data is presented, can be entirely customized. This shows only some of -many possible capabilities. +See the source: [bitehist.py](examples/tracing/bitehist.py). What this traces, +what this stores, and how the data is presented, can be entirely customized. +This shows only some of many possible capabilities. ## Installing @@ -60,9 +59,11 @@ pair of .c and .py files, and some are directories of files. Examples: -- examples/tracing/[bitehist.py](examples/tracing/bitehist.py) examples/tracing/[bitehist.c](examples/tracing/bitehist.c): Block I/O size histogram. [Examples](examples/tracing/bitehist_example.txt). -- examples/tracing/[disksnoop.py](examples/tracing/disksnoop.py) examples/tracing/[disksnoop.c](examples/tracing/disksnoop.c): Trace block device I/O latency. [Examples](examples/tracing/disksnoop_example.txt). +- examples/tracing/[bitehist.py](examples/tracing/bitehist.py): Block I/O size histogram. [Examples](examples/tracing/bitehist_example.txt). +- examples/tracing/[disksnoop.py](examples/tracing/disksnoop.py): Trace block device I/O latency. [Examples](examples/tracing/disksnoop_example.txt). - examples/[hello_world.py](examples/hello_world.py): Prints "Hello, World!" for new processes. +- examples/tracing/[nodejs_http_server.py](examples/tracing/nodejs_http_server.py): Trace Node.js HTTP server requests using USDT probes. +- examples/tracing/[task_switch.py](examples/tracing/task_switch.py): Count task switches with from and to PIDs. - examples/tracing/[tcpv4connect.py](examples/tracing/tcpv4connect.py): Trace TCP IPv4 active connections. [Examples](examples/tracing/tcpv4connect_example.txt). - examples/tracing/[trace_fields.py](examples/tracing/trace_fields.py): Simple example of printing fields from traced events. - examples/tracing/[urandomread.py](examples/tracing/urandomread.py): A kernel tracepoint example, which traces random:urandom_read. [Examples](examples/tracing/urandomread_example.txt). @@ -188,7 +189,7 @@ The BPF program always takes at least one argument, which is a pointer to the context for this type of program. Different program types have different calling conventions, but for this one we don't care so `void *` is fine. ```python -BPF(text='void kprobe__sys_clone(void *ctx) { bpf_trace_printk("Hello, World!\\n"); }').trace_print() +BPF(text='int kprobe__sys_clone(void *ctx) { bpf_trace_printk("Hello, World!\\n"); return 0; }').trace_print() ``` For this example, we will call the program every time `fork()` is called by a diff --git a/examples/hello_world.py b/examples/hello_world.py index 13c6eb00a33d..c23ed1cf1dc6 100755 --- a/examples/hello_world.py +++ b/examples/hello_world.py @@ -8,4 +8,4 @@ from bcc import BPF -BPF(text='void kprobe__sys_clone(void *ctx) { bpf_trace_printk("Hello, World!\\n"); }').trace_print() +BPF(text='int kprobe__sys_clone(void *ctx) { bpf_trace_printk("Hello, World!\\n"); return 0; }').trace_print() diff --git a/examples/tracing/bitehist.c b/examples/tracing/bitehist.c deleted file mode 100644 index 102ee4db9801..000000000000 --- a/examples/tracing/bitehist.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * bitehist.c Block I/O size histogram. - * For Linux, uses BCC, eBPF. See .py file. - * - * Copyright (c) 2013-2015 PLUMgrid, http://plumgrid.com - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 15-Aug-2015 Brendan Gregg Created this. - */ - -#include -#include - -BPF_HISTOGRAM(dist); - -int kprobe__blk_account_io_completion(struct pt_regs *ctx, struct request *req) -{ - dist.increment(bpf_log2l(req->__data_len / 1024)); - return 0; -} diff --git a/examples/tracing/bitehist.py b/examples/tracing/bitehist.py index cd309b4f2e86..1dee5dc05937 100755 --- a/examples/tracing/bitehist.py +++ b/examples/tracing/bitehist.py @@ -1,7 +1,7 @@ #!/usr/bin/python # # bitehist.py Block I/O size histogram. -# For Linux, uses BCC, eBPF. See .c file. +# For Linux, uses BCC, eBPF. Embedded C. # # Written as a basic example of using a histogram to show a distribution. # @@ -17,7 +17,18 @@ from time import sleep # load BPF program -b = BPF(src_file = "bitehist.c") +b = BPF(text=""" +#include +#include + +BPF_HISTOGRAM(dist); + +int kprobe__blk_account_io_completion(struct pt_regs *ctx, struct request *req) +{ + dist.increment(bpf_log2l(req->__data_len / 1024)); + return 0; +} +""") # header print("Tracing... Hit Ctrl-C to end.") diff --git a/examples/tracing/disksnoop.c b/examples/tracing/disksnoop.c deleted file mode 100644 index 8c2954915b56..000000000000 --- a/examples/tracing/disksnoop.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * disksnoop.c Trace block device I/O: basic version of iosnoop. - * For Linux, uses BCC, eBPF. See .py file. - * - * Copyright (c) 2015 Brendan Gregg. - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * 11-Aug-2015 Brendan Gregg Created this. - */ - -#include -#include - -BPF_HASH(start, struct request *); - -void trace_start(struct pt_regs *ctx, struct request *req) { - // stash start timestamp by request ptr - u64 ts = bpf_ktime_get_ns(); - - start.update(&req, &ts); -} - -void trace_completion(struct pt_regs *ctx, struct request *req) { - u64 *tsp, delta; - - tsp = start.lookup(&req); - if (tsp != 0) { - delta = bpf_ktime_get_ns() - *tsp; - bpf_trace_printk("%d %x %d\n", req->__data_len, - req->cmd_flags, delta / 1000); - start.delete(&req); - } -} diff --git a/examples/tracing/disksnoop.py b/examples/tracing/disksnoop.py index 206b61811f81..ed3dd819dd88 100755 --- a/examples/tracing/disksnoop.py +++ b/examples/tracing/disksnoop.py @@ -1,7 +1,7 @@ #!/usr/bin/python # # disksnoop.py Trace block device I/O: basic version of iosnoop. -# For Linux, uses BCC, eBPF. See .c file. +# For Linux, uses BCC, eBPF. Embedded C. # # Written as a basic example of tracing latency. # @@ -16,7 +16,32 @@ REQ_WRITE = 1 # from include/linux/blk_types.h # load BPF program -b = BPF(src_file="disksnoop.c") +b = BPF(text=""" +#include +#include + +BPF_HASH(start, struct request *); + +void trace_start(struct pt_regs *ctx, struct request *req) { + // stash start timestamp by request ptr + u64 ts = bpf_ktime_get_ns(); + + start.update(&req, &ts); +} + +void trace_completion(struct pt_regs *ctx, struct request *req) { + u64 *tsp, delta; + + tsp = start.lookup(&req); + if (tsp != 0) { + delta = bpf_ktime_get_ns() - *tsp; + bpf_trace_printk("%d %x %d\\n", req->__data_len, + req->cmd_flags, delta / 1000); + start.delete(&req); + } +} +""") + b.attach_kprobe(event="blk_start_request", fn_name="trace_start") b.attach_kprobe(event="blk_mq_start_request", fn_name="trace_start") b.attach_kprobe(event="blk_account_io_completion", fn_name="trace_completion") diff --git a/examples/tracing/task_switch.c b/examples/tracing/task_switch.c deleted file mode 100644 index 870e35fdc440..000000000000 --- a/examples/tracing/task_switch.c +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include - -struct key_t { - u32 prev_pid; - u32 curr_pid; -}; -// map_type, key_type, leaf_type, table_name, num_entry -BPF_TABLE("hash", struct key_t, u64, stats, 1024); -int count_sched(struct pt_regs *ctx, struct task_struct *prev) { - struct key_t key = {}; - u64 zero = 0, *val; - - key.curr_pid = bpf_get_current_pid_tgid(); - key.prev_pid = prev->pid; - - val = stats.lookup_or_init(&key, &zero); - (*val)++; - return 0; -} - diff --git a/examples/tracing/task_switch.py b/examples/tracing/task_switch.py index 43a4f3f8d0b2..6117ee3b7bb7 100755 --- a/examples/tracing/task_switch.py +++ b/examples/tracing/task_switch.py @@ -5,7 +5,28 @@ from bcc import BPF from time import sleep -b = BPF(src_file="task_switch.c") +b = BPF(text=""" +#include +#include + +struct key_t { + u32 prev_pid; + u32 curr_pid; +}; +// map_type, key_type, leaf_type, table_name, num_entry +BPF_TABLE("hash", struct key_t, u64, stats, 1024); +int count_sched(struct pt_regs *ctx, struct task_struct *prev) { + struct key_t key = {}; + u64 zero = 0, *val; + + key.curr_pid = bpf_get_current_pid_tgid(); + key.prev_pid = prev->pid; + + val = stats.lookup_or_init(&key, &zero); + (*val)++; + return 0; +} +""") b.attach_kprobe(event="finish_task_switch", fn_name="count_sched") # generate many schedule events