rbbcc 0.11.6 → 0.11.8
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/table.rb +8 -7
- 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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2e7ebcdc32959104f05d6d82656dc1002f4a35b47d2fd686a9a1b3e3ffc9ddc8
|
|
4
|
+
data.tar.gz: cc0aaeb6f9286c5703d78dbd31055d13cec731645e8bc21daaf9769c75304d06
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dbb371324fc56283175e2afae536972d795b22ed2f333129a5eed556366a3b1ec09a84c57c2589b7db204b7cba27e20d458ad240fbbccc85b1eb8dacccf70728
|
|
7
|
+
data.tar.gz: 360d1b9be834ff56b94d097c7292d77741c2eebdf8b7a29ee8e8e4cca3da26e72a0041a24c33ffd33f85e64f5d500aee7500ff2931508f81d6f880e2d78c801b
|
data/Gemfile.lock
CHANGED
data/lib/rbbcc/table.rb
CHANGED
|
@@ -479,13 +479,14 @@ module RbBCC
|
|
|
479
479
|
[Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP, Fiddle::TYPE_INT]
|
|
480
480
|
) do |_dummy, data, size|
|
|
481
481
|
begin
|
|
482
|
-
|
|
483
|
-
ret
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
482
|
+
ret = callback.call(ctx, data, size)
|
|
483
|
+
if ret.is_a?(Numeric)
|
|
484
|
+
ret.to_i
|
|
485
|
+
else
|
|
486
|
+
# Callback for ringbufs should _always_ return an integer.
|
|
487
|
+
# simply fall back to returning 0 when failed
|
|
488
|
+
0
|
|
489
|
+
end
|
|
489
490
|
rescue => e
|
|
490
491
|
if Fiddle.last_error == 32 # EPIPE
|
|
491
492
|
exit
|
data/lib/rbbcc/version.rb
CHANGED
data/rbbcc.gemspec
CHANGED
|
@@ -15,9 +15,12 @@ Gem::Specification.new do |spec|
|
|
|
15
15
|
|
|
16
16
|
# Specify which files should be added to the gem when it is released.
|
|
17
17
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
18
|
-
spec.files
|
|
19
|
-
`git ls-files -z`.split("\x0").reject
|
|
18
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
|
19
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
|
20
|
+
f.match(%r{^(test|spec|features|docs|examples)/}) || f.match(/\.(gif|jpe?g|png)\Z/)
|
|
21
|
+
end
|
|
20
22
|
end
|
|
23
|
+
|
|
21
24
|
spec.bindir = "exe"
|
|
22
25
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
23
26
|
spec.require_paths = ["lib"]
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rbbcc
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.11.
|
|
4
|
+
version: 0.11.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Uchio Kondo
|
|
@@ -53,66 +53,6 @@ files:
|
|
|
53
53
|
- ci/Dockerfile.0.17.0-2.7.2
|
|
54
54
|
- ci/Dockerfile.0.17.0-3.0.0
|
|
55
55
|
- ci/Dockerfile.ci_base
|
|
56
|
-
- docs/README.md
|
|
57
|
-
- docs/answers/01-hello-world.rb
|
|
58
|
-
- docs/answers/02-sys_sync.rb
|
|
59
|
-
- docs/answers/03-hello_fields.rb
|
|
60
|
-
- docs/answers/04-sync_timing.rb
|
|
61
|
-
- docs/answers/05-sync_count.rb
|
|
62
|
-
- docs/answers/06-disksnoop.rb
|
|
63
|
-
- docs/answers/07-hello_perf_output.rb
|
|
64
|
-
- docs/answers/08-sync_perf_output.rb
|
|
65
|
-
- docs/answers/09-bitehist.rb
|
|
66
|
-
- docs/answers/10-disklatency.rb
|
|
67
|
-
- docs/answers/11-vfsreadlat.c
|
|
68
|
-
- docs/answers/11-vfsreadlat.rb
|
|
69
|
-
- docs/answers/12-urandomread.rb
|
|
70
|
-
- docs/answers/13-disksnoop_fixed.rb
|
|
71
|
-
- docs/answers/14-strlen_count.rb
|
|
72
|
-
- docs/answers/15-nodejs_http_server.rb
|
|
73
|
-
- docs/answers/16-task_switch.c
|
|
74
|
-
- docs/answers/16-task_switch.rb
|
|
75
|
-
- docs/answers/node-server.js
|
|
76
|
-
- docs/getting_started.md
|
|
77
|
-
- docs/projects_using_rbbcc.md
|
|
78
|
-
- docs/tutorial_bcc_ruby_developer.md
|
|
79
|
-
- docs/tutorial_bcc_ruby_developer_japanese.md
|
|
80
|
-
- examples/bitehist.rb
|
|
81
|
-
- examples/charty/Gemfile
|
|
82
|
-
- examples/charty/Gemfile.lock
|
|
83
|
-
- examples/charty/bitehist-unicode.rb
|
|
84
|
-
- examples/collectsyscall.rb
|
|
85
|
-
- examples/dddos.rb
|
|
86
|
-
- examples/disksnoop.rb
|
|
87
|
-
- examples/dns_blocker.rb
|
|
88
|
-
- examples/example.gif
|
|
89
|
-
- examples/extract_arg.rb
|
|
90
|
-
- examples/hello_fields.rb
|
|
91
|
-
- examples/hello_perf_output.rb
|
|
92
|
-
- examples/hello_ring_buffer.rb
|
|
93
|
-
- examples/hello_world.rb
|
|
94
|
-
- examples/kvm_hypercall.rb
|
|
95
|
-
- examples/lsm_sockblock.rb
|
|
96
|
-
- examples/mallocstack.rb
|
|
97
|
-
- examples/networking/http_filter/http-parse-simple.c
|
|
98
|
-
- examples/networking/http_filter/http-parse-simple.rb
|
|
99
|
-
- examples/pin_maps_a.rb
|
|
100
|
-
- examples/pin_maps_b.rb
|
|
101
|
-
- examples/py-orig/sockblock.py
|
|
102
|
-
- examples/ringbuf_pin_a.rb
|
|
103
|
-
- examples/ringbuf_pin_b.rb
|
|
104
|
-
- examples/ruby_usdt.rb
|
|
105
|
-
- examples/sbrk_trace.rb
|
|
106
|
-
- examples/ssl_http_trace.rb
|
|
107
|
-
- examples/syscalluname.rb
|
|
108
|
-
- examples/table.rb
|
|
109
|
-
- examples/tools/bashreadline.rb
|
|
110
|
-
- examples/tools/execsnoop.rb
|
|
111
|
-
- examples/tools/runqlat.rb
|
|
112
|
-
- examples/urandomread-explicit.rb
|
|
113
|
-
- examples/urandomread.rb
|
|
114
|
-
- examples/usdt-test.rb
|
|
115
|
-
- examples/usdt.rb
|
|
116
56
|
- exe/rbbcc
|
|
117
57
|
- lib/rbbcc.rb
|
|
118
58
|
- lib/rbbcc/bcc.rb
|
|
@@ -149,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
149
89
|
- !ruby/object:Gem::Version
|
|
150
90
|
version: '0'
|
|
151
91
|
requirements: []
|
|
152
|
-
rubygems_version: 4.0.
|
|
92
|
+
rubygems_version: 4.0.10
|
|
153
93
|
specification_version: 4
|
|
154
94
|
summary: BCC port for MRI
|
|
155
95
|
test_files: []
|
data/docs/README.md
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
# RbBCC Docs
|
|
2
|
-
|
|
3
|
-
* [Getting Started](getting_started.md)
|
|
4
|
-
* [Ruby Tutorial](tutorial_bcc_ruby_developer.md)
|
|
5
|
-
* [Projects Using RbBCC](projects_using_rbbcc.md)
|
|
6
|
-
|
|
7
|
-
**Please see also [BCC itself's README](https://github.com/iovisor/bcc/#readme) and [docs](https://github.com/iovisor/bcc/tree/master/docs).**
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# Original hello_world.py:
|
|
3
|
-
# Copyright (c) PLUMgrid, Inc.
|
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License")
|
|
5
|
-
#
|
|
6
|
-
# This Ruby version follows the Apache License 2.0
|
|
7
|
-
|
|
8
|
-
# run in project examples directory with:
|
|
9
|
-
# sudo ./hello_world.rb"
|
|
10
|
-
# see trace_fields.rb for a longer example
|
|
11
|
-
|
|
12
|
-
require "rbbcc"
|
|
13
|
-
include RbBCC
|
|
14
|
-
|
|
15
|
-
# This may not work for 4.17 on x64, you need replace kprobe__sys_clone with kprobe____x64_sys_clone
|
|
16
|
-
BCC.new(text: 'int kprobe__sys_clone(void *ctx) { bpf_trace_printk("Hello, World!\\n"); return 0; }').trace_print
|
data/docs/answers/02-sys_sync.rb
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# Licensed under the Apache License, Version 2.0 (the "License")
|
|
3
|
-
|
|
4
|
-
require "rbbcc"
|
|
5
|
-
include RbBCC
|
|
6
|
-
|
|
7
|
-
puts "Tracing sys_sync()... Ctrl-C to end."
|
|
8
|
-
begin
|
|
9
|
-
BCC.new(text: <<~BPF).trace_print
|
|
10
|
-
int kprobe__sys_sync(void *ctx) {
|
|
11
|
-
bpf_trace_printk("sys_sync() called\\n");
|
|
12
|
-
return 0;
|
|
13
|
-
}
|
|
14
|
-
BPF
|
|
15
|
-
rescue Interrupt
|
|
16
|
-
puts
|
|
17
|
-
puts "Done"
|
|
18
|
-
end
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# Licensed under the Apache License, Version 2.0 (the "License")
|
|
3
|
-
|
|
4
|
-
require "rbbcc"
|
|
5
|
-
include RbBCC
|
|
6
|
-
|
|
7
|
-
# define BPF program
|
|
8
|
-
prog = <<BPF
|
|
9
|
-
int hello(void *ctx) {
|
|
10
|
-
bpf_trace_printk("Hello, World!\\n");
|
|
11
|
-
return 0;
|
|
12
|
-
}
|
|
13
|
-
BPF
|
|
14
|
-
|
|
15
|
-
# load BPF program
|
|
16
|
-
b = BCC.new(text: prog)
|
|
17
|
-
b.attach_kprobe(event: b.get_syscall_fnname("clone"), fn_name: "hello")
|
|
18
|
-
|
|
19
|
-
# header
|
|
20
|
-
puts("%-18s %-16s %-6s %s" % ["TIME(s)", "COMM", "PID", "MESSAGE"])
|
|
21
|
-
|
|
22
|
-
# format output
|
|
23
|
-
begin
|
|
24
|
-
b.trace_fields do |task, pid, cpu, flags, ts, msg|
|
|
25
|
-
print("%-18.9f %-16s %-6d %s" % [ts, task, pid, msg])
|
|
26
|
-
end
|
|
27
|
-
rescue Interrupt
|
|
28
|
-
puts
|
|
29
|
-
puts "Done"
|
|
30
|
-
rescue => e
|
|
31
|
-
p e
|
|
32
|
-
retry
|
|
33
|
-
end
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# Original sync_timing.py:
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License")
|
|
4
|
-
#
|
|
5
|
-
# This Ruby version follows the Apache License 2.0
|
|
6
|
-
|
|
7
|
-
require "rbbcc"
|
|
8
|
-
include RbBCC
|
|
9
|
-
|
|
10
|
-
# load BPF program
|
|
11
|
-
b = BCC.new(text: <<BPF)
|
|
12
|
-
#include <uapi/linux/ptrace.h>
|
|
13
|
-
|
|
14
|
-
BPF_HASH(last);
|
|
15
|
-
|
|
16
|
-
int do_trace(struct pt_regs *ctx) {
|
|
17
|
-
u64 ts, *tsp, delta, key = 0;
|
|
18
|
-
|
|
19
|
-
// attempt to read stored timestamp
|
|
20
|
-
tsp = last.lookup(&key);
|
|
21
|
-
if (tsp != 0) {
|
|
22
|
-
delta = bpf_ktime_get_ns() - *tsp;
|
|
23
|
-
if (delta < 1000000000) {
|
|
24
|
-
// output if time is less than 1 second
|
|
25
|
-
bpf_trace_printk("%d\\n", delta / 1000000);
|
|
26
|
-
}
|
|
27
|
-
last.delete(&key);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// update stored timestamp
|
|
31
|
-
ts = bpf_ktime_get_ns();
|
|
32
|
-
last.update(&key, &ts);
|
|
33
|
-
return 0;
|
|
34
|
-
}
|
|
35
|
-
BPF
|
|
36
|
-
|
|
37
|
-
b.attach_kprobe(event: b.get_syscall_fnname("sync"), fn_name: "do_trace")
|
|
38
|
-
puts("Tracing for quick sync's... Ctrl-C to end")
|
|
39
|
-
|
|
40
|
-
# format output
|
|
41
|
-
start = 0
|
|
42
|
-
b.trace_fields do |task, pid, cpu, flags, ts, ms|
|
|
43
|
-
start = ts.to_f if start.zero?
|
|
44
|
-
ts = ts.to_f - start
|
|
45
|
-
puts("At time %.2f s: multiple syncs detected, last %s ms ago" % [ts, ms.chomp])
|
|
46
|
-
end
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# Licensed under the Apache License, Version 2.0 (the "License")
|
|
3
|
-
|
|
4
|
-
require "rbbcc"
|
|
5
|
-
include RbBCC
|
|
6
|
-
|
|
7
|
-
# load BPF program
|
|
8
|
-
b = BCC.new(text: <<BPF)
|
|
9
|
-
#include <uapi/linux/ptrace.h>
|
|
10
|
-
|
|
11
|
-
BPF_HASH(last);
|
|
12
|
-
|
|
13
|
-
int do_trace(struct pt_regs *ctx) {
|
|
14
|
-
u64 ts, *tsp, delta, key = 0, counter_key = 1, zero = 0;
|
|
15
|
-
|
|
16
|
-
// initialize counter key
|
|
17
|
-
if (last.lookup_or_try_init(&counter_key, &zero))
|
|
18
|
-
last.increment(counter_key);
|
|
19
|
-
|
|
20
|
-
// attempt to read stored timestamp
|
|
21
|
-
tsp = last.lookup(&key);
|
|
22
|
-
if (tsp != 0) {
|
|
23
|
-
delta = bpf_ktime_get_ns() - *tsp;
|
|
24
|
-
if (delta < 1000000000) {
|
|
25
|
-
// output if time is less than 1 second
|
|
26
|
-
bpf_trace_printk("%d\\n", delta / 1000000);
|
|
27
|
-
}
|
|
28
|
-
last.delete(&key);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// update stored timestamp
|
|
32
|
-
ts = bpf_ktime_get_ns();
|
|
33
|
-
last.update(&key, &ts);
|
|
34
|
-
return 0;
|
|
35
|
-
}
|
|
36
|
-
BPF
|
|
37
|
-
|
|
38
|
-
COUNTER_KEY = 1
|
|
39
|
-
|
|
40
|
-
b.attach_kprobe(event: b.get_syscall_fnname("sync"), fn_name: "do_trace")
|
|
41
|
-
puts("Tracing for quick sync's... Ctrl-C to end")
|
|
42
|
-
|
|
43
|
-
# format output
|
|
44
|
-
start = 0
|
|
45
|
-
begin
|
|
46
|
-
b.trace_fields do |task, pid, cpu, flags, ts, ms|
|
|
47
|
-
start = ts.to_f if start.zero?
|
|
48
|
-
ts = ts.to_f - start
|
|
49
|
-
puts("At time %.2f s: multiple syncs detected, last %s ms ago" % [ts, ms.chomp])
|
|
50
|
-
end
|
|
51
|
-
rescue Interrupt
|
|
52
|
-
table = b["last"]
|
|
53
|
-
puts "Count of sys_sync: %d" % table[COUNTER_KEY].to_bcc_value
|
|
54
|
-
end
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
#
|
|
3
|
-
# disksnoop.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
|
-
require 'rbbcc'
|
|
14
|
-
include RbBCC
|
|
15
|
-
|
|
16
|
-
REQ_WRITE = 1 # from include/linux/blk_types.h
|
|
17
|
-
|
|
18
|
-
# load BPF program
|
|
19
|
-
b = BCC.new(text: <<CLANG)
|
|
20
|
-
#include <uapi/linux/ptrace.h>
|
|
21
|
-
#include <linux/blkdev.h>
|
|
22
|
-
|
|
23
|
-
BPF_HASH(start, struct request *);
|
|
24
|
-
|
|
25
|
-
void trace_start(struct pt_regs *ctx, struct request *req) {
|
|
26
|
-
// stash start timestamp by request ptr
|
|
27
|
-
u64 ts = bpf_ktime_get_ns();
|
|
28
|
-
|
|
29
|
-
start.update(&req, &ts);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
void trace_completion(struct pt_regs *ctx, struct request *req) {
|
|
33
|
-
u64 *tsp, delta;
|
|
34
|
-
|
|
35
|
-
tsp = start.lookup(&req);
|
|
36
|
-
if (tsp != 0) {
|
|
37
|
-
delta = bpf_ktime_get_ns() - *tsp;
|
|
38
|
-
bpf_trace_printk("%d %x %d\\n", req->__data_len,
|
|
39
|
-
req->cmd_flags, delta / 1000);
|
|
40
|
-
start.delete(&req);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
CLANG
|
|
44
|
-
|
|
45
|
-
b.attach_kprobe(event: "blk_start_request", fn_name: "trace_start") if BCC.get_kprobe_functions('blk_start_request')
|
|
46
|
-
b.attach_kprobe(event: "blk_mq_start_request", fn_name: "trace_start")
|
|
47
|
-
b.attach_kprobe(event: "blk_account_io_completion", fn_name: "trace_completion")
|
|
48
|
-
|
|
49
|
-
# header
|
|
50
|
-
puts("%-18s %-2s %-7s %8s" % ["TIME(s)", "T", "BYTES", "LAT(ms)"])
|
|
51
|
-
|
|
52
|
-
# format output
|
|
53
|
-
loop do
|
|
54
|
-
begin
|
|
55
|
-
task, pid, cpu, flags, ts, msg = b.trace_fields
|
|
56
|
-
bytes_s, bflags_s, us_s = msg.split
|
|
57
|
-
|
|
58
|
-
if (bflags_s.to_i(16) & REQ_WRITE).nonzero?
|
|
59
|
-
type_s = "W"
|
|
60
|
-
elsif bytes_s == "0" # see blk_fill_rwbs() for logic
|
|
61
|
-
type_s = "M"
|
|
62
|
-
else
|
|
63
|
-
type_s = "R"
|
|
64
|
-
end
|
|
65
|
-
ms = us_s.to_i.to_f / 1000
|
|
66
|
-
|
|
67
|
-
puts("%-18.9f %-2s %-7s %8.2f" % [ts, type_s, bytes_s, ms])
|
|
68
|
-
rescue Interrupt
|
|
69
|
-
exit
|
|
70
|
-
end
|
|
71
|
-
end
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
#
|
|
3
|
-
# This is a Hello World example that uses BPF_PERF_OUTPUT.
|
|
4
|
-
# Ported from hello_perf_output.py
|
|
5
|
-
|
|
6
|
-
require 'rbbcc'
|
|
7
|
-
include RbBCC
|
|
8
|
-
|
|
9
|
-
# define BPF program
|
|
10
|
-
prog = """
|
|
11
|
-
#include <linux/sched.h>
|
|
12
|
-
|
|
13
|
-
// define output data structure in C
|
|
14
|
-
struct data_t {
|
|
15
|
-
u32 pid;
|
|
16
|
-
u64 ts;
|
|
17
|
-
char comm[TASK_COMM_LEN];
|
|
18
|
-
};
|
|
19
|
-
BPF_PERF_OUTPUT(events);
|
|
20
|
-
|
|
21
|
-
int hello(struct pt_regs *ctx) {
|
|
22
|
-
struct data_t data = {};
|
|
23
|
-
|
|
24
|
-
data.pid = bpf_get_current_pid_tgid();
|
|
25
|
-
data.ts = bpf_ktime_get_ns();
|
|
26
|
-
bpf_get_current_comm(&data.comm, sizeof(data.comm));
|
|
27
|
-
|
|
28
|
-
events.perf_submit(ctx, &data, sizeof(data));
|
|
29
|
-
|
|
30
|
-
return 0;
|
|
31
|
-
}
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
# load BPF program
|
|
35
|
-
b = BCC.new(text: prog)
|
|
36
|
-
b.attach_kprobe(event: b.get_syscall_fnname("clone"), fn_name: "hello")
|
|
37
|
-
|
|
38
|
-
# header
|
|
39
|
-
puts("%-18s %-16s %-6s %s" % ["TIME(s)", "COMM", "PID", "MESSAGE"])
|
|
40
|
-
|
|
41
|
-
# process event
|
|
42
|
-
start = 0
|
|
43
|
-
print_event = lambda { |cpu, data, size|
|
|
44
|
-
event = b["events"].event(data)
|
|
45
|
-
if start == 0
|
|
46
|
-
start = event.ts
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
time_s = ((event.ts - start).to_f) / 1000000000
|
|
50
|
-
puts("%-18.9f %-16s %-6d %s" % [time_s, event.comm, event.pid,
|
|
51
|
-
"Hello, perf_output!"])
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
# loop with callback to print_event
|
|
55
|
-
b["events"].open_perf_buffer(&print_event)
|
|
56
|
-
|
|
57
|
-
loop do
|
|
58
|
-
b.perf_buffer_poll()
|
|
59
|
-
end
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# Licensed under the Apache License, Version 2.0 (the "License")
|
|
3
|
-
|
|
4
|
-
require "rbbcc"
|
|
5
|
-
include RbBCC
|
|
6
|
-
|
|
7
|
-
# load BPF program
|
|
8
|
-
b = BCC.new(text: <<BPF)
|
|
9
|
-
#include <uapi/linux/ptrace.h>
|
|
10
|
-
|
|
11
|
-
struct data_t {
|
|
12
|
-
u32 pid;
|
|
13
|
-
u64 ts;
|
|
14
|
-
u64 delta;
|
|
15
|
-
};
|
|
16
|
-
BPF_PERF_OUTPUT(events);
|
|
17
|
-
BPF_HASH(last);
|
|
18
|
-
|
|
19
|
-
int do_trace(struct pt_regs *ctx) {
|
|
20
|
-
u64 ts, *tsp, delta, key = 0;
|
|
21
|
-
|
|
22
|
-
// attempt to read stored timestamp
|
|
23
|
-
tsp = last.lookup(&key);
|
|
24
|
-
if (tsp != 0) {
|
|
25
|
-
struct data_t data = {};
|
|
26
|
-
delta = bpf_ktime_get_ns() - *tsp;
|
|
27
|
-
if (delta < 1000000000) {
|
|
28
|
-
data.pid = bpf_get_current_pid_tgid();
|
|
29
|
-
data.ts = bpf_ktime_get_ns();
|
|
30
|
-
data.delta = delta;
|
|
31
|
-
events.perf_submit(ctx, &data, sizeof(data));
|
|
32
|
-
}
|
|
33
|
-
last.delete(&key);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// update stored timestamp
|
|
37
|
-
ts = bpf_ktime_get_ns();
|
|
38
|
-
last.update(&key, &ts);
|
|
39
|
-
return 0;
|
|
40
|
-
}
|
|
41
|
-
BPF
|
|
42
|
-
|
|
43
|
-
b.attach_kprobe(event: b.get_syscall_fnname("sync"), fn_name: "do_trace")
|
|
44
|
-
puts("Tracing for quick sync's... Ctrl-C to end")
|
|
45
|
-
|
|
46
|
-
# format output
|
|
47
|
-
start = 0
|
|
48
|
-
b["events"].open_perf_buffer do |_, data, _|
|
|
49
|
-
event = b["events"].event(data)
|
|
50
|
-
if start == 0
|
|
51
|
-
start = event.ts
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
time_s = ((event.ts - start).to_f) / 1_000_000_000
|
|
55
|
-
puts("At time %.2f s: multiple syncs detected, last %s ms ago" % [time_s, event.delta / 1_000_000])
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
loop do
|
|
59
|
-
b.perf_buffer_poll()
|
|
60
|
-
end
|
data/docs/answers/09-bitehist.rb
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# Licensed under the Apache License, Version 2.0 (the "License")
|
|
3
|
-
|
|
4
|
-
require 'rbbcc'
|
|
5
|
-
include RbBCC
|
|
6
|
-
|
|
7
|
-
# load BPF program
|
|
8
|
-
b = BCC.new(text: <<BPF)
|
|
9
|
-
#include <uapi/linux/ptrace.h>
|
|
10
|
-
#include <linux/blkdev.h>
|
|
11
|
-
|
|
12
|
-
BPF_HISTOGRAM(dist);
|
|
13
|
-
|
|
14
|
-
int kprobe__blk_account_io_completion(struct pt_regs *ctx, struct request *req)
|
|
15
|
-
{
|
|
16
|
-
dist.increment(bpf_log2l(req->__data_len / 1024));
|
|
17
|
-
return 0;
|
|
18
|
-
}
|
|
19
|
-
BPF
|
|
20
|
-
|
|
21
|
-
# header
|
|
22
|
-
puts("Tracing... Hit Ctrl-C to end.")
|
|
23
|
-
|
|
24
|
-
# trace until Ctrl-C
|
|
25
|
-
begin
|
|
26
|
-
loop { sleep 0.1 }
|
|
27
|
-
rescue Interrupt
|
|
28
|
-
puts
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# output
|
|
32
|
-
b["dist"].print_log2_hist("kbytes")
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
# Licensed under the Apache License, Version 2.0 (the "License")
|
|
3
|
-
|
|
4
|
-
require 'rbbcc'
|
|
5
|
-
include RbBCC
|
|
6
|
-
|
|
7
|
-
b = BCC.new(text: <<BPF)
|
|
8
|
-
#include <uapi/linux/ptrace.h>
|
|
9
|
-
#include <linux/blkdev.h>
|
|
10
|
-
|
|
11
|
-
BPF_HASH(start, struct request *);
|
|
12
|
-
BPF_HISTOGRAM(dist);
|
|
13
|
-
|
|
14
|
-
// note this program mixes R/W
|
|
15
|
-
// For next step, handle req->cmd_flags and prepare hist hash per op.
|
|
16
|
-
|
|
17
|
-
void trace_start(struct pt_regs *ctx, struct request *req) {
|
|
18
|
-
// stash start timestamp by request ptr
|
|
19
|
-
u64 ts = bpf_ktime_get_ns();
|
|
20
|
-
|
|
21
|
-
start.update(&req, &ts);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
void trace_completion(struct pt_regs *ctx, struct request *req) {
|
|
25
|
-
u64 *tsp, delta;
|
|
26
|
-
|
|
27
|
-
tsp = start.lookup(&req);
|
|
28
|
-
if (tsp != 0) {
|
|
29
|
-
delta = bpf_ktime_get_ns() - *tsp;
|
|
30
|
-
dist.increment(bpf_log2l(delta / 1000)); // us
|
|
31
|
-
start.delete(&req);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
BPF
|
|
35
|
-
|
|
36
|
-
b.attach_kprobe(event: "blk_start_request", fn_name: "trace_start") if BCC.get_kprobe_functions('blk_start_request')
|
|
37
|
-
b.attach_kprobe(event: "blk_mq_start_request", fn_name: "trace_start")
|
|
38
|
-
b.attach_kprobe(event: "blk_account_io_completion", fn_name: "trace_completion")
|
|
39
|
-
|
|
40
|
-
# header
|
|
41
|
-
puts("Tracing... Hit Ctrl-C to end.")
|
|
42
|
-
|
|
43
|
-
# trace until Ctrl-C
|
|
44
|
-
begin
|
|
45
|
-
loop { sleep 0.1 }
|
|
46
|
-
rescue Interrupt
|
|
47
|
-
puts
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# output
|
|
51
|
-
b["dist"].print_log2_hist("usec")
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* From: https://github.com/iovisor/bcc/blob/master/examples/tracing/vfsreadlat.c
|
|
3
|
-
*
|
|
4
|
-
* vfsreadlat.c VFS read latency distribution.
|
|
5
|
-
* For Linux, uses BCC, eBPF. See .py/.rb file.
|
|
6
|
-
*
|
|
7
|
-
* Copyright (c) 2013-2015 PLUMgrid, http://plumgrid.com
|
|
8
|
-
* This program is free software; you can redistribute it and/or
|
|
9
|
-
* modify it under the terms of version 2 of the GNU General Public
|
|
10
|
-
* License as published by the Free Software Foundation.
|
|
11
|
-
*
|
|
12
|
-
* 15-Aug-2015 Brendan Gregg Created this.
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
#include <uapi/linux/ptrace.h>
|
|
16
|
-
|
|
17
|
-
BPF_HASH(start, u32);
|
|
18
|
-
BPF_HISTOGRAM(dist);
|
|
19
|
-
|
|
20
|
-
int do_entry(struct pt_regs *ctx)
|
|
21
|
-
{
|
|
22
|
-
u32 pid;
|
|
23
|
-
u64 ts, *val;
|
|
24
|
-
|
|
25
|
-
pid = bpf_get_current_pid_tgid();
|
|
26
|
-
ts = bpf_ktime_get_ns();
|
|
27
|
-
start.update(&pid, &ts);
|
|
28
|
-
return 0;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
int do_return(struct pt_regs *ctx)
|
|
32
|
-
{
|
|
33
|
-
u32 pid;
|
|
34
|
-
u64 *tsp, delta;
|
|
35
|
-
|
|
36
|
-
pid = bpf_get_current_pid_tgid();
|
|
37
|
-
tsp = start.lookup(&pid);
|
|
38
|
-
|
|
39
|
-
if (tsp != 0) {
|
|
40
|
-
delta = bpf_ktime_get_ns() - *tsp;
|
|
41
|
-
dist.increment(bpf_log2l(delta / 1000));
|
|
42
|
-
start.delete(&pid);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return 0;
|
|
46
|
-
}
|