rbbcc 0.11.6 → 0.11.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/rbbcc/version.rb +1 -1
- data/rbbcc.gemspec +5 -2
- metadata +2 -62
- data/docs/README.md +0 -7
- data/docs/answers/01-hello-world.rb +0 -16
- data/docs/answers/02-sys_sync.rb +0 -18
- data/docs/answers/03-hello_fields.rb +0 -33
- data/docs/answers/04-sync_timing.rb +0 -46
- data/docs/answers/05-sync_count.rb +0 -54
- data/docs/answers/06-disksnoop.rb +0 -71
- data/docs/answers/07-hello_perf_output.rb +0 -59
- data/docs/answers/08-sync_perf_output.rb +0 -60
- data/docs/answers/09-bitehist.rb +0 -32
- data/docs/answers/10-disklatency.rb +0 -51
- data/docs/answers/11-vfsreadlat.c +0 -46
- data/docs/answers/11-vfsreadlat.rb +0 -66
- data/docs/answers/12-urandomread.rb +0 -38
- data/docs/answers/13-disksnoop_fixed.rb +0 -108
- data/docs/answers/14-strlen_count.rb +0 -46
- data/docs/answers/15-nodejs_http_server.rb +0 -44
- data/docs/answers/16-task_switch.c +0 -23
- data/docs/answers/16-task_switch.rb +0 -17
- data/docs/answers/node-server.js +0 -11
- data/docs/getting_started.md +0 -154
- data/docs/projects_using_rbbcc.md +0 -43
- data/docs/tutorial_bcc_ruby_developer.md +0 -774
- data/docs/tutorial_bcc_ruby_developer_japanese.md +0 -770
- data/examples/bitehist.rb +0 -46
- data/examples/charty/Gemfile +0 -11
- data/examples/charty/Gemfile.lock +0 -48
- data/examples/charty/bitehist-unicode.rb +0 -87
- data/examples/collectsyscall.rb +0 -182
- data/examples/dddos.rb +0 -112
- data/examples/disksnoop.rb +0 -73
- data/examples/dns_blocker.rb +0 -134
- data/examples/example.gif +0 -0
- data/examples/extract_arg.rb +0 -26
- data/examples/hello_fields.rb +0 -32
- data/examples/hello_perf_output.rb +0 -64
- data/examples/hello_ring_buffer.rb +0 -64
- data/examples/hello_world.rb +0 -6
- data/examples/kvm_hypercall.rb +0 -69
- data/examples/lsm_sockblock.rb +0 -141
- data/examples/mallocstack.rb +0 -63
- data/examples/networking/http_filter/http-parse-simple.c +0 -114
- data/examples/networking/http_filter/http-parse-simple.rb +0 -85
- data/examples/pin_maps_a.rb +0 -88
- data/examples/pin_maps_b.rb +0 -71
- data/examples/py-orig/sockblock.py +0 -119
- data/examples/ringbuf_pin_a.rb +0 -51
- data/examples/ringbuf_pin_b.rb +0 -29
- data/examples/ruby_usdt.rb +0 -105
- data/examples/sbrk_trace.rb +0 -204
- data/examples/ssl_http_trace.rb +0 -274
- data/examples/syscalluname.rb +0 -39
- data/examples/table.rb +0 -15
- data/examples/tools/bashreadline.rb +0 -83
- data/examples/tools/execsnoop.rb +0 -229
- data/examples/tools/runqlat.rb +0 -148
- data/examples/urandomread-explicit.rb +0 -58
- data/examples/urandomread.rb +0 -39
- data/examples/usdt-test.rb +0 -6
- data/examples/usdt.rb +0 -26
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
#
|
|
3
|
-
# Original: from vfsreadlat.py
|
|
4
|
-
# Copyright (c) 2015 Brendan Gregg.
|
|
5
|
-
# Licensed under the Apache License, Version 2.0 (the "License")
|
|
6
|
-
# Ruby version follows.
|
|
7
|
-
#
|
|
8
|
-
# vfsreadlat.rb VFS read latency distribution.
|
|
9
|
-
# For Linux, uses BCC, eBPF. See .c file.
|
|
10
|
-
#
|
|
11
|
-
# Written as a basic example of a function latency distribution histogram.
|
|
12
|
-
#
|
|
13
|
-
# USAGE: vfsreadlat.rb [interval [count]]
|
|
14
|
-
#
|
|
15
|
-
# The default interval is 5 seconds. A Ctrl-C will print the partially
|
|
16
|
-
# gathered histogram then exit.
|
|
17
|
-
|
|
18
|
-
require "rbbcc"
|
|
19
|
-
include RbBCC
|
|
20
|
-
|
|
21
|
-
def usage
|
|
22
|
-
puts("USAGE: %s [interval [count]]" % $0)
|
|
23
|
-
exit
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
# arguments
|
|
27
|
-
interval = 5
|
|
28
|
-
count = -1
|
|
29
|
-
if ARGV.size > 0
|
|
30
|
-
begin
|
|
31
|
-
interval = ARGV[0].to_i
|
|
32
|
-
raise if interval == 0
|
|
33
|
-
count = ARGV[1].to_i if ARGV[1]
|
|
34
|
-
rescue => e # also catches -h, --help
|
|
35
|
-
usage()
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
# load BPF program
|
|
40
|
-
b = BCC.new(src_file: "11-vfsreadlat.c")
|
|
41
|
-
b.attach_kprobe(event: "vfs_read", fn_name: "do_entry")
|
|
42
|
-
b.attach_kretprobe(event: "vfs_read", fn_name: "do_return")
|
|
43
|
-
|
|
44
|
-
# header
|
|
45
|
-
print("Tracing... Hit Ctrl-C to end.")
|
|
46
|
-
|
|
47
|
-
# output
|
|
48
|
-
cycle = 0
|
|
49
|
-
do_exit = false
|
|
50
|
-
loop do
|
|
51
|
-
if count > 0
|
|
52
|
-
cycle += 1
|
|
53
|
-
exit if cycle > count
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
begin
|
|
57
|
-
sleep(interval)
|
|
58
|
-
rescue Interrupt
|
|
59
|
-
do_exit = true
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
puts
|
|
63
|
-
b["dist"].print_log2_hist("usecs")
|
|
64
|
-
b["dist"].clear
|
|
65
|
-
exit if do_exit
|
|
66
|
-
end
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
#
|
|
3
|
-
# urandomread.rb Example of instrumenting a kernel tracepoint.
|
|
4
|
-
# For Linux, uses BCC, BPF. Embedded C.
|
|
5
|
-
#
|
|
6
|
-
# REQUIRES: Linux 4.7+ (BPF_PROG_TYPE_TRACEPOINT support).
|
|
7
|
-
#
|
|
8
|
-
# Test by running this, then in another shell, run:
|
|
9
|
-
# dd if=/dev/urandom of=/dev/null bs=1k count=5
|
|
10
|
-
#
|
|
11
|
-
# Original urandomread.py Copyright 2016 Netflix, Inc.
|
|
12
|
-
# Licensed under the Apache License, Version 2.0 (the "License")
|
|
13
|
-
# Ruby version follows.
|
|
14
|
-
|
|
15
|
-
require 'rbbcc'
|
|
16
|
-
include RbBCC
|
|
17
|
-
|
|
18
|
-
b = BCC.new(text: <<BPF)
|
|
19
|
-
TRACEPOINT_PROBE(random, urandom_read) {
|
|
20
|
-
// args is from /sys/kernel/debug/tracing/events/random/urandom_read/format
|
|
21
|
-
bpf_trace_printk("%d\\n", args->got_bits);
|
|
22
|
-
return 0;
|
|
23
|
-
}
|
|
24
|
-
BPF
|
|
25
|
-
|
|
26
|
-
# header
|
|
27
|
-
puts("%-18s %-16s %-6s %s" % ["TIME(s)", "COMM", "PID", "GOTBITS"])
|
|
28
|
-
|
|
29
|
-
# format output
|
|
30
|
-
loop do
|
|
31
|
-
begin
|
|
32
|
-
b.trace_fields do |task, pid, cpu, flags, ts, msg|
|
|
33
|
-
puts("%-18.9f %-16s %-6d %s" % [ts, task, pid, msg])
|
|
34
|
-
end
|
|
35
|
-
rescue Interrupt
|
|
36
|
-
exit
|
|
37
|
-
end
|
|
38
|
-
end
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
#
|
|
3
|
-
# disksnoop_fixed.rb Trace block device I/O: basic version of iosnoop.
|
|
4
|
-
# For Linux, uses BCC, eBPF. Embedded C.
|
|
5
|
-
# This is ported from original disksnoop.py
|
|
6
|
-
#
|
|
7
|
-
# Written as a basic example of tracing latency.
|
|
8
|
-
#
|
|
9
|
-
# Licensed under the Apache License, Version 2.0 (the "License")
|
|
10
|
-
#
|
|
11
|
-
# 11-Aug-2015 Brendan Gregg Created disksnoop.py
|
|
12
|
-
|
|
13
|
-
=begin
|
|
14
|
-
name: block_rq_issue
|
|
15
|
-
ID: 1093
|
|
16
|
-
format:
|
|
17
|
-
field:unsigned short common_type; offset:0; size:2; signed:0;
|
|
18
|
-
field:unsigned char common_flags; offset:2; size:1; signed:0;
|
|
19
|
-
field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
|
|
20
|
-
field:int common_pid; offset:4; size:4; signed:1;
|
|
21
|
-
|
|
22
|
-
field:dev_t dev; offset:8; size:4; signed:0;
|
|
23
|
-
field:sector_t sector; offset:16; size:8; signed:0;
|
|
24
|
-
field:unsigned int nr_sector; offset:24; size:4; signed:0;
|
|
25
|
-
field:unsigned int bytes; offset:28; size:4; signed:0;
|
|
26
|
-
field:char rwbs[8]; offset:32; size:8; signed:1;
|
|
27
|
-
field:char comm[16]; offset:40; size:16; signed:1;
|
|
28
|
-
field:__data_loc char[] cmd; offset:56; size:4; signed:1;
|
|
29
|
-
|
|
30
|
-
print fmt: "%d,%d %s %u (%s) %llu + %u [%s]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, REC->bytes, __get_str(cmd), (unsigned long long)REC->sector, REC->nr_sector, REC->comm
|
|
31
|
-
|
|
32
|
-
name: block_rq_complete
|
|
33
|
-
ID: 1095
|
|
34
|
-
format:
|
|
35
|
-
field:unsigned short common_type; offset:0; size:2; signed:0;
|
|
36
|
-
field:unsigned char common_flags; offset:2; size:1; signed:0;
|
|
37
|
-
field:unsigned char common_preempt_count; offset:3; size:1; signed:0;
|
|
38
|
-
field:int common_pid; offset:4; size:4; signed:1;
|
|
39
|
-
|
|
40
|
-
field:dev_t dev; offset:8; size:4; signed:0;
|
|
41
|
-
field:sector_t sector; offset:16; size:8; signed:0;
|
|
42
|
-
field:unsigned int nr_sector; offset:24; size:4; signed:0;
|
|
43
|
-
field:int error; offset:28; size:4; signed:1;
|
|
44
|
-
field:char rwbs[8]; offset:32; size:8; signed:1;
|
|
45
|
-
field:__data_loc char[] cmd; offset:40; size:4; signed:1;
|
|
46
|
-
|
|
47
|
-
print fmt: "%d,%d %s (%s) %llu + %u [%d]", ((unsigned int) ((REC->dev) >> 20)), ((unsigned int) ((REC->dev) & ((1U << 20) - 1))), REC->rwbs, __get_str(cmd), (unsigned long long)REC->sector, REC->nr_sector, REC->error
|
|
48
|
-
|
|
49
|
-
in kernel 5.0.
|
|
50
|
-
This implementation shows the count of sector.
|
|
51
|
-
=end
|
|
52
|
-
|
|
53
|
-
require 'rbbcc'
|
|
54
|
-
include RbBCC
|
|
55
|
-
|
|
56
|
-
# load BPF program
|
|
57
|
-
b = BCC.new(text: <<CLANG)
|
|
58
|
-
#include <uapi/linux/ptrace.h>
|
|
59
|
-
#include <linux/blkdev.h>
|
|
60
|
-
|
|
61
|
-
BPF_HASH(start, u32);
|
|
62
|
-
|
|
63
|
-
TRACEPOINT_PROBE(block, block_rq_issue) {
|
|
64
|
-
// stash start timestamp by request ptr
|
|
65
|
-
u64 ts = bpf_ktime_get_ns();
|
|
66
|
-
u32 tid = bpf_get_current_pid_tgid();
|
|
67
|
-
|
|
68
|
-
start.update(&tid, &ts);
|
|
69
|
-
return 0;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
TRACEPOINT_PROBE(block, block_rq_complete) {
|
|
73
|
-
u64 *tsp, delta;
|
|
74
|
-
u32 tid = bpf_get_current_pid_tgid();
|
|
75
|
-
|
|
76
|
-
tsp = start.lookup(&tid);
|
|
77
|
-
if (tsp != 0) {
|
|
78
|
-
char dst[8];
|
|
79
|
-
int i;
|
|
80
|
-
delta = bpf_ktime_get_ns() - *tsp;
|
|
81
|
-
if (bpf_probe_read_str(dst, sizeof(dst), args->rwbs) < 0) {
|
|
82
|
-
dst[0] = '?';
|
|
83
|
-
for(i = 1; i < sizeof(dst); ++i)
|
|
84
|
-
dst[i] = 0;
|
|
85
|
-
}
|
|
86
|
-
bpf_trace_printk("%d %s %d\\n", args->nr_sector,
|
|
87
|
-
dst, delta / 1000);
|
|
88
|
-
start.delete(&tid);
|
|
89
|
-
}
|
|
90
|
-
return 0;
|
|
91
|
-
}
|
|
92
|
-
CLANG
|
|
93
|
-
|
|
94
|
-
# header
|
|
95
|
-
puts("%-18s %-8s %-7s %8s" % ["TIME(s)", "RWBS", "SECTORS", "LAT(ms)"])
|
|
96
|
-
|
|
97
|
-
# format output
|
|
98
|
-
loop do
|
|
99
|
-
begin
|
|
100
|
-
task, pid, cpu, flags, ts, msg = b.trace_fields
|
|
101
|
-
sector_s, rwbs, us_s = msg.split
|
|
102
|
-
ms = us_s.to_i.to_f / 1000
|
|
103
|
-
|
|
104
|
-
puts("%-18.9f %-8s %-7s %8.2f" % [ts, rwbs, sector_s, ms])
|
|
105
|
-
rescue Interrupt
|
|
106
|
-
exit
|
|
107
|
-
end
|
|
108
|
-
end
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
require 'rbbcc'
|
|
2
|
-
include RbBCC
|
|
3
|
-
|
|
4
|
-
# load BPF program
|
|
5
|
-
b = BCC.new(text: <<BPF)
|
|
6
|
-
#include <uapi/linux/ptrace.h>
|
|
7
|
-
|
|
8
|
-
struct key_t {
|
|
9
|
-
char c[80];
|
|
10
|
-
};
|
|
11
|
-
BPF_HASH(counts, struct key_t);
|
|
12
|
-
|
|
13
|
-
int count(struct pt_regs *ctx) {
|
|
14
|
-
if (!PT_REGS_PARM1(ctx))
|
|
15
|
-
return 0;
|
|
16
|
-
|
|
17
|
-
struct key_t key = {};
|
|
18
|
-
u64 zero = 0, *val;
|
|
19
|
-
|
|
20
|
-
bpf_probe_read(&key.c, sizeof(key.c), (void *)PT_REGS_PARM1(ctx));
|
|
21
|
-
// could also use `counts.increment(key)`
|
|
22
|
-
val = counts.lookup_or_try_init(&key, &zero);
|
|
23
|
-
if (val) {
|
|
24
|
-
(*val)++;
|
|
25
|
-
}
|
|
26
|
-
return 0;
|
|
27
|
-
};
|
|
28
|
-
BPF
|
|
29
|
-
b.attach_uprobe(name: "c", sym: "strlen", fn_name: "count")
|
|
30
|
-
|
|
31
|
-
# header
|
|
32
|
-
print("Tracing strlen()... Hit Ctrl-C to end.")
|
|
33
|
-
|
|
34
|
-
# sleep until Ctrl-C
|
|
35
|
-
begin
|
|
36
|
-
sleep(99999999)
|
|
37
|
-
rescue Interrupt
|
|
38
|
-
puts
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# print output
|
|
42
|
-
puts("%10s %s" % ["COUNT", "STRING"])
|
|
43
|
-
counts = b.get_table("counts")
|
|
44
|
-
counts.items.sort_by{|k, v| v.to_bcc_value }.each do |k, v|
|
|
45
|
-
puts("%10d %s" % [v.to_bcc_value, k.to_bcc_value.c])
|
|
46
|
-
end
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
require 'rbbcc'
|
|
2
|
-
include RbBCC
|
|
3
|
-
|
|
4
|
-
if ARGV.size != 1
|
|
5
|
-
print("USAGE: #{$0} PID")
|
|
6
|
-
exit()
|
|
7
|
-
end
|
|
8
|
-
pid = ARGV[0]
|
|
9
|
-
debug = !!ENV['DEBUG']
|
|
10
|
-
|
|
11
|
-
# load BPF program
|
|
12
|
-
bpf_text = <<BPF
|
|
13
|
-
#include <uapi/linux/ptrace.h>
|
|
14
|
-
int do_trace(struct pt_regs *ctx) {
|
|
15
|
-
uint64_t addr;
|
|
16
|
-
char path[128]={0};
|
|
17
|
-
bpf_usdt_readarg(6, ctx, &addr);
|
|
18
|
-
bpf_probe_read(&path, sizeof(path), (void *)addr);
|
|
19
|
-
bpf_trace_printk("path:%s\\n", path);
|
|
20
|
-
return 0;
|
|
21
|
-
};
|
|
22
|
-
BPF
|
|
23
|
-
|
|
24
|
-
# enable USDT probe from given PID
|
|
25
|
-
u = USDT.new(pid: pid.to_i)
|
|
26
|
-
u.enable_probe(probe: "http__server__request", fn_name: "do_trace")
|
|
27
|
-
if debug
|
|
28
|
-
puts(u.get_text)
|
|
29
|
-
puts(bpf_text)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# initialize BPF
|
|
33
|
-
b = BCC.new(text: bpf_text, usdt_contexts: [u])
|
|
34
|
-
|
|
35
|
-
puts("%-18s %-16s %-6s %s" % ["TIME(s)", "COMM", "PID", "ARGS"])
|
|
36
|
-
loop do
|
|
37
|
-
begin
|
|
38
|
-
b.trace_fields do |task, pid, cpu, flags, ts, msg|
|
|
39
|
-
puts("%-18.9f %-16s %-6d %s" % [ts, task, pid, msg])
|
|
40
|
-
end
|
|
41
|
-
rescue Interrupt
|
|
42
|
-
exit
|
|
43
|
-
end
|
|
44
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
#include <uapi/linux/ptrace.h>
|
|
2
|
-
#include <linux/sched.h>
|
|
3
|
-
|
|
4
|
-
struct key_t {
|
|
5
|
-
u32 prev_pid;
|
|
6
|
-
u32 curr_pid;
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
BPF_HASH(stats, struct key_t, u64, 1024);
|
|
10
|
-
int count_sched(struct pt_regs *ctx, struct task_struct *prev) {
|
|
11
|
-
struct key_t key = {};
|
|
12
|
-
u64 zero = 0, *val;
|
|
13
|
-
|
|
14
|
-
key.curr_pid = bpf_get_current_pid_tgid();
|
|
15
|
-
key.prev_pid = prev->pid;
|
|
16
|
-
|
|
17
|
-
// could also use `stats.increment(key);`
|
|
18
|
-
val = stats.lookup_or_try_init(&key, &zero);
|
|
19
|
-
if (val) {
|
|
20
|
-
(*val)++;
|
|
21
|
-
}
|
|
22
|
-
return 0;
|
|
23
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# Original task_switch.rb Copyright (c) PLUMgrid, Inc.
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License")
|
|
4
|
-
|
|
5
|
-
require 'rbbcc'
|
|
6
|
-
include RbBCC
|
|
7
|
-
|
|
8
|
-
b = BCC.new(src_file: "16-task_switch.c")
|
|
9
|
-
b.attach_kprobe(event: "finish_task_switch", fn_name: "count_sched")
|
|
10
|
-
|
|
11
|
-
# generate many schedule events
|
|
12
|
-
100.times { sleep 0.01 }
|
|
13
|
-
|
|
14
|
-
b["stats"].each do |_k, v|
|
|
15
|
-
k = _k[0, 8].unpack("i! i!") # Handling pointer without type!!
|
|
16
|
-
puts("task_switch[%5d->%5d]=%u" % [k[0], k[1], v.to_bcc_value])
|
|
17
|
-
end
|
data/docs/answers/node-server.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
var http = require("http");
|
|
2
|
-
|
|
3
|
-
var server = http.createServer(function (req, res) {
|
|
4
|
-
res.writeHead(200, {"Content-Type": "text/plain"});
|
|
5
|
-
res.end("Sample node.js server, returns contents in any path.\n");
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
var port = process.env.PORT || 8081;
|
|
9
|
-
server.listen(port, function() {
|
|
10
|
-
console.log("Do curl http://localhost:" + port);
|
|
11
|
-
});
|
data/docs/getting_started.md
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
# Getting Started
|
|
2
|
-
|
|
3
|
-
RbBCC is a project to utilize the power of eBPF/BCC from Ruby.
|
|
4
|
-
|
|
5
|
-
## Setup
|
|
6
|
-
|
|
7
|
-
RbBCC requires `libbcc.so` version **0.11.0 or 0.10.0**(we plan to support newer version of libbcc, such as 0.12.0; but it may be done after rbbcc 1.0...).
|
|
8
|
-
|
|
9
|
-
BTW we do not need to install header files, becuase current version of RbBCC uses the functionality of libbcc via ffi(We use MRI's standard library **fiddle**, not external gems).
|
|
10
|
-
|
|
11
|
-
We can install this shared library via package `libbcc` from official iovisor project repo:
|
|
12
|
-
|
|
13
|
-
```console
|
|
14
|
-
# e.g. In Ubuntu:
|
|
15
|
-
$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4052245BD4284CDD
|
|
16
|
-
$ echo "deb https://repo.iovisor.org/apt/$(lsb_release -cs) $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/iovisor.list
|
|
17
|
-
$ sudo apt-get update
|
|
18
|
-
$ sudo apt-get install libbcc
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
For more imformation, see [bcc's official doc](https://github.com/iovisor/bcc/blob/master/INSTALL.md).
|
|
22
|
-
|
|
23
|
-
After installed libbcc, you can create project hierarchy like:
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
.
|
|
27
|
-
├── Gemfile
|
|
28
|
-
└── tools
|
|
29
|
-
└── hello_world.rb
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
with `Gemfile` below:
|
|
33
|
-
|
|
34
|
-
```ruby
|
|
35
|
-
source "https://rubygems.org"
|
|
36
|
-
|
|
37
|
-
gem "rbbcc"
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Then run `bundle install`.
|
|
41
|
-
|
|
42
|
-
### With docker
|
|
43
|
-
|
|
44
|
-
_TBD_
|
|
45
|
-
|
|
46
|
-
## Hello world from Linux kernel!
|
|
47
|
-
|
|
48
|
-
Creating `tools/hello_world.rb` as:
|
|
49
|
-
|
|
50
|
-
```ruby
|
|
51
|
-
#!/usr/bin/env ruby
|
|
52
|
-
|
|
53
|
-
require 'rbbcc'
|
|
54
|
-
include RbBCC
|
|
55
|
-
|
|
56
|
-
text = <<CLANG
|
|
57
|
-
int kprobe__sys_clone(void *ctx)
|
|
58
|
-
{
|
|
59
|
-
bpf_trace_printk("Hello, World!\\n");
|
|
60
|
-
return 0;
|
|
61
|
-
}
|
|
62
|
-
CLANG
|
|
63
|
-
|
|
64
|
-
b = BCC.new(text: text)
|
|
65
|
-
printf("%-18s %-16s %-6s %s\n", "TIME(s)", "COMM", "PID", "value")
|
|
66
|
-
|
|
67
|
-
b.trace_fields do |task, pid, cpu, flags, ts, msg|
|
|
68
|
-
printf("%-18.9f %-16s %-6d %s", ts, task, pid, msg)
|
|
69
|
-
end
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
Then invoke this Ruby script. BCC requires to run as a priveleged user.
|
|
73
|
-
|
|
74
|
-
```console
|
|
75
|
-
$ sudo bundle exec ruby tools/hello_world.rb
|
|
76
|
-
Found fnc: kprobe__sys_clone
|
|
77
|
-
Attach: p___x64_sys_clone
|
|
78
|
-
TIME(s) COMM PID value
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
Open another terminal and hit commands, like `curl https://www.ruby-lang.org/`.
|
|
82
|
-
|
|
83
|
-
Then RbBCC process displays what kind of program invokes another program with message `Hello, World`.
|
|
84
|
-
|
|
85
|
-
```console
|
|
86
|
-
TIME(s) COMM PID value
|
|
87
|
-
109979.625639000 bash 7591 Hello, World!
|
|
88
|
-
109979.632267000 curl 29098 Hello, World!
|
|
89
|
-
109981.467914000 bash 7591 Hello, World!
|
|
90
|
-
109981.474290000 curl 29100 Hello, World!
|
|
91
|
-
109984.913358000 bash 7591 Hello, World!
|
|
92
|
-
109984.921165000 curl 29102 Hello, World!
|
|
93
|
-
...
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
These lines are displayed by a kernel hook of `clone(2)(internally: sys_clone)` call. The bash command like `curl, grep, ping...` internally call `sys_clone` to fork new processes, and RbBCC traces these kernel calls with a very small cost.
|
|
97
|
-
|
|
98
|
-
Then, change the Ruby(and internal C) codes into this like:
|
|
99
|
-
|
|
100
|
-
```ruby
|
|
101
|
-
#!/usr/bin/env ruby
|
|
102
|
-
|
|
103
|
-
require 'rbbcc'
|
|
104
|
-
include RbBCC
|
|
105
|
-
|
|
106
|
-
text = <<CLANG
|
|
107
|
-
#include <uapi/linux/ptrace.h>
|
|
108
|
-
|
|
109
|
-
int printret(struct pt_regs *ctx) {
|
|
110
|
-
char str[80] = {};
|
|
111
|
-
u32 pid;
|
|
112
|
-
if (!PT_REGS_RC(ctx))
|
|
113
|
-
return 0;
|
|
114
|
-
pid = bpf_get_current_pid_tgid();
|
|
115
|
-
bpf_probe_read(&str, sizeof(str), (void *)PT_REGS_RC(ctx));
|
|
116
|
-
bpf_trace_printk("[%d]input: %s\\n", pid, str);
|
|
117
|
-
|
|
118
|
-
return 0;
|
|
119
|
-
};
|
|
120
|
-
CLANG
|
|
121
|
-
|
|
122
|
-
b = BCC.new(text: text)
|
|
123
|
-
b.attach_uretprobe(name: "/bin/bash", sym: "readline", fn_name: "printret")
|
|
124
|
-
|
|
125
|
-
printf("%-18s %-16s %s\n", "TIME(s)", "COMM", "value")
|
|
126
|
-
b.trace_fields do |task, pid, cpu, flags, ts, msg|
|
|
127
|
-
printf("%-18.9f %-16s %s", ts, task, msg)
|
|
128
|
-
end
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
Run again:
|
|
132
|
-
|
|
133
|
-
```console
|
|
134
|
-
$ sudo bundle exec ruby tools/hello_world.rb
|
|
135
|
-
Found fnc: printret
|
|
136
|
-
Attach: p__bin_bash_0xad900
|
|
137
|
-
TIME(s) COMM value
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
And open another "bash" terminal again. When you hit a command to this bash in any session, any input strings are snooped and shown in the tracing process. This is all of the trace result of return in `readline()` function from user program "bash". RbBCC can detect where and how it occurs.
|
|
141
|
-
|
|
142
|
-
```console
|
|
143
|
-
TIME(s) COMM value
|
|
144
|
-
1554.284390000 bash [5457]input: curl localhost
|
|
145
|
-
1559.425699000 bash [5457]input: ping 8.8.8.8
|
|
146
|
-
1565.805870000 bash [5457]input: sudo cat /etc/passwd
|
|
147
|
-
...
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
----
|
|
151
|
-
|
|
152
|
-
For more use case and information. Please see [`examples`](../examples/) directory and (especially for C API) BCC's official document.
|
|
153
|
-
|
|
154
|
-
* [bcc Reference Guide](https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md)
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# Projects Using RbBCC
|
|
2
|
-
|
|
3
|
-
## bpfql
|
|
4
|
-
|
|
5
|
-
[bpfql](https://github.com/udzura/bpfql) is a tool to run an eBPF tracing query, using YAML or Ruby DSL.
|
|
6
|
-
|
|
7
|
-
```ruby
|
|
8
|
-
BPFQL do
|
|
9
|
-
select "*"
|
|
10
|
-
from "tracepoint:random:urandom_read"
|
|
11
|
-
where "comm", is: "ruby"
|
|
12
|
-
end
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
```console
|
|
16
|
-
$ sudo bundle exec bpfql examples/random.rb
|
|
17
|
-
Found fnc: tracepoint__random__urandom_read
|
|
18
|
-
Attach: random:urandom_read
|
|
19
|
-
TS COMM PID GOT_BITS POOL_LEFT INPUT_LEFT
|
|
20
|
-
0.000000000 ruby 32485 128 0 2451
|
|
21
|
-
0.002465663 ruby 32485 128 0 2451
|
|
22
|
-
^CExiting bpfql...
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
See [its repo](https://github.com/udzura/bpfql) for more details.
|
|
26
|
-
|
|
27
|
-
## rack-ebpf and rack application tracing
|
|
28
|
-
|
|
29
|
-
[rack-ebpf](https://github.com/udzura/rack-ebpf) is a rack middleware that invoke USDT probes every time start/end the requests.
|
|
30
|
-
|
|
31
|
-
Combine this rack middleware and `rack-ebpf-run` command, we can trace and analyze system stats per request.
|
|
32
|
-
|
|
33
|
-
e.g.
|
|
34
|
-
|
|
35
|
-
* Count of syscall invocations(like read, write) per request
|
|
36
|
-
* Consumed time for syscall ops(like read, write) per request
|
|
37
|
-
* Created Ruby objects per request, using Ruby itself's USDT (this requires ruby itself as `--enable-dtrace` build)
|
|
38
|
-
|
|
39
|
-
For detailed usage, see [rack-ebpf's repo](https://github.com/udzura/rack-ebpf)
|
|
40
|
-
|
|
41
|
-
----
|
|
42
|
-
|
|
43
|
-
Also we're going to prepare some BCC tools made with Ruby. TBA!
|