rbbcc 0.11.5 → 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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/lib/rbbcc/consts.rb +5 -1
  4. data/lib/rbbcc/table.rb +35 -3
  5. data/lib/rbbcc/version.rb +1 -1
  6. data/rbbcc.gemspec +5 -2
  7. metadata +2 -60
  8. data/docs/README.md +0 -7
  9. data/docs/answers/01-hello-world.rb +0 -16
  10. data/docs/answers/02-sys_sync.rb +0 -18
  11. data/docs/answers/03-hello_fields.rb +0 -33
  12. data/docs/answers/04-sync_timing.rb +0 -46
  13. data/docs/answers/05-sync_count.rb +0 -54
  14. data/docs/answers/06-disksnoop.rb +0 -71
  15. data/docs/answers/07-hello_perf_output.rb +0 -59
  16. data/docs/answers/08-sync_perf_output.rb +0 -60
  17. data/docs/answers/09-bitehist.rb +0 -32
  18. data/docs/answers/10-disklatency.rb +0 -51
  19. data/docs/answers/11-vfsreadlat.c +0 -46
  20. data/docs/answers/11-vfsreadlat.rb +0 -66
  21. data/docs/answers/12-urandomread.rb +0 -38
  22. data/docs/answers/13-disksnoop_fixed.rb +0 -108
  23. data/docs/answers/14-strlen_count.rb +0 -46
  24. data/docs/answers/15-nodejs_http_server.rb +0 -44
  25. data/docs/answers/16-task_switch.c +0 -23
  26. data/docs/answers/16-task_switch.rb +0 -17
  27. data/docs/answers/node-server.js +0 -11
  28. data/docs/getting_started.md +0 -154
  29. data/docs/projects_using_rbbcc.md +0 -43
  30. data/docs/tutorial_bcc_ruby_developer.md +0 -774
  31. data/docs/tutorial_bcc_ruby_developer_japanese.md +0 -770
  32. data/examples/bitehist.rb +0 -46
  33. data/examples/charty/Gemfile +0 -11
  34. data/examples/charty/Gemfile.lock +0 -48
  35. data/examples/charty/bitehist-unicode.rb +0 -87
  36. data/examples/collectsyscall.rb +0 -182
  37. data/examples/dddos.rb +0 -112
  38. data/examples/disksnoop.rb +0 -73
  39. data/examples/dns_blocker.rb +0 -134
  40. data/examples/example.gif +0 -0
  41. data/examples/extract_arg.rb +0 -26
  42. data/examples/hello_fields.rb +0 -32
  43. data/examples/hello_perf_output.rb +0 -64
  44. data/examples/hello_ring_buffer.rb +0 -64
  45. data/examples/hello_world.rb +0 -6
  46. data/examples/kvm_hypercall.rb +0 -69
  47. data/examples/lsm_sockblock.rb +0 -141
  48. data/examples/mallocstack.rb +0 -63
  49. data/examples/networking/http_filter/http-parse-simple.c +0 -114
  50. data/examples/networking/http_filter/http-parse-simple.rb +0 -85
  51. data/examples/pin_maps_a.rb +0 -88
  52. data/examples/pin_maps_b.rb +0 -71
  53. data/examples/py-orig/sockblock.py +0 -119
  54. data/examples/ruby_usdt.rb +0 -105
  55. data/examples/sbrk_trace.rb +0 -204
  56. data/examples/ssl_http_trace.rb +0 -274
  57. data/examples/syscalluname.rb +0 -39
  58. data/examples/table.rb +0 -15
  59. data/examples/tools/bashreadline.rb +0 -83
  60. data/examples/tools/execsnoop.rb +0 -229
  61. data/examples/tools/runqlat.rb +0 -148
  62. data/examples/urandomread-explicit.rb +0 -58
  63. data/examples/urandomread.rb +0 -39
  64. data/examples/usdt-test.rb +0 -6
  65. data/examples/usdt.rb +0 -26
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4757d8938ba54c8aaab6d26a1d8cf824c325b8591130d1cf65ee13c0e411e99f
4
- data.tar.gz: e41edc20c58336f5aa3e1670f2f001a9cdc829291a8bd63ab53d309790b81f5c
3
+ metadata.gz: 59d0fb02bff1acabccf1f231bd3642bfa3da9ef1fc796c580d8c1d9c4c5098bc
4
+ data.tar.gz: 5e033fa5c3957b1d7e822eec06c4bff9f1158046a292897f61401206d56fff9d
5
5
  SHA512:
6
- metadata.gz: 43cb1ba2fa891fc6fd970b5a48b45c28d9fff967e25ef02ed5cb7b09ddc96a91dc0e4740dbc59b9bc78f312613b76f6b7f68de9ee41bf860caddf1fb0a948c15
7
- data.tar.gz: e6e8321874553ba7df4f0529477d6bea3a35f4956b704bd32bfeb409d7f43a1a59f4f9484619891e1351ed278eee42c4edda7a17d176c3b911e4c5a1dee5716a
6
+ metadata.gz: ca57cd8e17b0035c4e670e0a3fc18ee53544cd14b81a5cdf62b91a504b848b59b3ad1f38658ae68fff0c1cc33126f36ea708b73b5378a2d83223651ce0a5441d
7
+ data.tar.gz: d37158b96887c9500ee791209d44bc03902efda99466623eccff0d1de83c18dc6fca174beb37c50a4d36d0caa84f3dbf2b6e1aee21470a47e9cc2af7ce2fbc10
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rbbcc (0.11.5)
4
+ rbbcc (0.11.7)
5
5
  fiddle
6
6
 
7
7
  GEM
data/lib/rbbcc/consts.rb CHANGED
@@ -1,5 +1,9 @@
1
1
  module RbBCC
2
- module BPF
2
+ class BCC
3
+ end
4
+ BPF = BCC # avoid confuse from python port
5
+
6
+ class BPF
3
7
  # From bpf_prog_type in uapi/linux/bpf.h
4
8
  SOCKET_FILTER = 1
5
9
  KPROBE = 2
data/lib/rbbcc/table.rb CHANGED
@@ -40,6 +40,8 @@ module RbBCC
40
40
  fields << [field_type, field_name].join(" ")
41
41
  end
42
42
  end
43
+ return nil if fields.empty?
44
+
43
45
  klass = Fiddle::Importer.struct(fields)
44
46
  char_ps = fields.select {|f| f =~ /^char\[(\d+)\] ([_a-zA-Z0-9]+)/ }
45
47
  unless char_ps.empty?
@@ -280,6 +282,11 @@ module RbBCC
280
282
  false # TODO: implement me in the future
281
283
  end
282
284
 
285
+ # Just a wrapper to BCC class method
286
+ def pin!(path)
287
+ BCC.pin!(self.map_fd, path)
288
+ end
289
+
283
290
  private
284
291
  def normalize_key(key)
285
292
  case key
@@ -368,7 +375,7 @@ module RbBCC
368
375
  end
369
376
 
370
377
  def event(data)
371
- @event_class ||= get_event_class
378
+ @event_class ||= (get_event_class || self.leaftype)
372
379
  ev = @event_class.malloc
373
380
  Fiddle::Pointer.new(ev.to_ptr)[0, @event_class.size] = data[0, @event_class.size]
374
381
  return ev
@@ -429,7 +436,28 @@ module RbBCC
429
436
 
430
437
  class RingBuf < TableBase
431
438
  include EventTypeSupported
432
-
439
+
440
+ # Make a dynamic BCC program to load the pinned ringbuf map
441
+ def self.from_pin(path, leaftype, size, name: "events")
442
+ map_fd = Clib.bpf_obj_get(path)
443
+ if map_fd < 0
444
+ raise SystemCallError.new("Could not open pinned map", Fiddle.last_error)
445
+ end
446
+ leaftype_typename = case leaftype
447
+ when /\Astruct\s+(\w+)\s+{/m
448
+ "struct #{Regexp.last_match(1)}"
449
+ else
450
+ leaftype
451
+ end
452
+
453
+ prog = <<~CLANG
454
+ #{leaftype}
455
+ BPF_TABLE_PINNED("ringbuf", u32, #{leaftype_typename}, #{name}, #{size}, "#{path}");
456
+ CLANG
457
+ b = BCC.new(text: prog)
458
+ b[name.to_s]
459
+ end
460
+
433
461
  def initialize(bpf, map_id, map_fd, keytype, leaftype, name: nil)
434
462
  super
435
463
  @_ringbuf = nil
@@ -438,7 +466,7 @@ module RbBCC
438
466
  end
439
467
 
440
468
  def event(data)
441
- @event_class ||= get_event_class
469
+ @event_class ||= (get_event_class || self.leaftype)
442
470
  ev = @event_class.malloc
443
471
  Fiddle::Pointer.new(ev.to_ptr)[0, @event_class.size] = data[0, @event_class.size]
444
472
  return ev
@@ -470,6 +498,10 @@ module RbBCC
470
498
  @bpf._open_ring_buffer(@map_fd, fn, ctx)
471
499
  nil
472
500
  end
501
+
502
+ def ring_buffer_poll(timeout=-1)
503
+ @bpf.ring_buffer_poll(timeout)
504
+ end
473
505
  end
474
506
 
475
507
  class StackTrace < TableBase
data/lib/rbbcc/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RbBCC
2
- VERSION = "0.11.5"
2
+ VERSION = "0.11.7"
3
3
  end
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 = Dir.chdir(File.expand_path('..', __FILE__)) do
19
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
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.5
4
+ version: 0.11.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Uchio Kondo
@@ -53,64 +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/ruby_usdt.rb
103
- - examples/sbrk_trace.rb
104
- - examples/ssl_http_trace.rb
105
- - examples/syscalluname.rb
106
- - examples/table.rb
107
- - examples/tools/bashreadline.rb
108
- - examples/tools/execsnoop.rb
109
- - examples/tools/runqlat.rb
110
- - examples/urandomread-explicit.rb
111
- - examples/urandomread.rb
112
- - examples/usdt-test.rb
113
- - examples/usdt.rb
114
56
  - exe/rbbcc
115
57
  - lib/rbbcc.rb
116
58
  - lib/rbbcc/bcc.rb
@@ -147,7 +89,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
147
89
  - !ruby/object:Gem::Version
148
90
  version: '0'
149
91
  requirements: []
150
- rubygems_version: 4.0.6
92
+ rubygems_version: 4.0.10
151
93
  specification_version: 4
152
94
  summary: BCC port for MRI
153
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
@@ -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
@@ -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")