rbbcc 0.5.0 → 0.6.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b09e8de1a9fb9b045fc7cd7b00bb6cd54e2af818c8c66caed5b82370f4db612
4
- data.tar.gz: 02b6c61e958a72b7d69a892dfa856823d12078393327138c523653bfc3110779
3
+ metadata.gz: 92b4487b6e8f5b72aad25113da967b51b2feb064361676b093441b6fd0bab672
4
+ data.tar.gz: 03d71e58ddebacdbf41f0c1ad4422bcfa1b9acdda3ac568068a2a8751b594a97
5
5
  SHA512:
6
- metadata.gz: 2fefae013cd7a13666ae61fe19284fae49fdad67ac30692e13ab445be71b9ce788177e261e0ac884bc15e491dce2e8895dd374c623256c2dec3dab3158dc583e
7
- data.tar.gz: d879de7d56899578ae483d85d9fd073cca4d84fcc5adaa465e86dacb152585c395cbdb2e563b69612577abfae07c2f500acdecd4a515c0c8f833ff586afe7158
6
+ metadata.gz: bb9234154fe245bf001676f1a6e7b1e5bcce31e4962bd0d646746d1f3c286722def93899877c9a200a516fd33366ef7c73fcf2a7a22731fb76225edb5477f449
7
+ data.tar.gz: 89415cbd8cadade4b49b53b5fd1c024198bfbd3424e0d95ecaf8e00381495570e171bcf54f4c395ddf40d762821da1425945761d80166aef724e038f43ae0f3c
@@ -10,10 +10,12 @@ blocks:
10
10
  jobs:
11
11
  - name: ruby test
12
12
  matrix:
13
+ - env_var: RUBY_VERSION
14
+ values: [ "2.6.5", "2.6.6", "2.7.1" ]
13
15
  - env_var: LIBBCC_VERSION
14
16
  values: [ "0.12.0", "0.11.0", "0.10.0" ]
15
17
  commands:
16
18
  - sem-version c 7
17
- - sem-version ruby 2.6.5
19
+ - sem-version ruby $RUBY_VERSION
18
20
  - checkout
19
21
  - ./semaphore.sh
data/Gemfile CHANGED
@@ -7,3 +7,12 @@ gem "bundler", "~> 2.0"
7
7
  gem "rake", "~> 13.0"
8
8
  gem "pry", "~> 0.12"
9
9
  gem "minitest", ">= 5"
10
+
11
+ group :omnibus_package do
12
+ gem "appbundler"
13
+ gem "specific_install"
14
+ end
15
+
16
+ group :plugin_dev do
17
+ gem "rbbcc-hello", git: "https://github.com/udzura/rbbcc-hello.git"
18
+ end
@@ -1,28 +1,46 @@
1
+ GIT
2
+ remote: https://github.com/udzura/rbbcc-hello.git
3
+ revision: 2e1af47d22e7cc92e970dc6c058e113cf00821db
4
+ specs:
5
+ rbbcc-hello (0.1.0)
6
+ rbbcc
7
+
1
8
  PATH
2
9
  remote: .
3
10
  specs:
4
- rbbcc (0.5.0)
11
+ rbbcc (0.6.4)
5
12
 
6
13
  GEM
7
14
  remote: https://rubygems.org/
8
15
  specs:
9
- coderay (1.1.2)
10
- method_source (0.9.2)
11
- minitest (5.14.0)
12
- pry (0.12.2)
13
- coderay (~> 1.1.0)
14
- method_source (~> 0.9.0)
16
+ appbundler (0.13.2)
17
+ mixlib-cli (>= 1.4, < 3.0)
18
+ mixlib-shellout (>= 2.0, < 4.0)
19
+ chef-utils (16.6.14)
20
+ coderay (1.1.3)
21
+ method_source (1.0.0)
22
+ minitest (5.14.2)
23
+ mixlib-cli (2.1.8)
24
+ mixlib-shellout (3.2.2)
25
+ chef-utils
26
+ pry (0.13.1)
27
+ coderay (~> 1.1)
28
+ method_source (~> 1.0)
15
29
  rake (13.0.1)
30
+ specific_install (0.3.5)
16
31
 
17
32
  PLATFORMS
18
33
  ruby
19
34
 
20
35
  DEPENDENCIES
36
+ appbundler
21
37
  bundler (~> 2.0)
22
38
  minitest (>= 5)
23
39
  pry (~> 0.12)
24
40
  rake (~> 13.0)
25
41
  rbbcc!
42
+ rbbcc-hello!
43
+ specific_install
26
44
 
27
45
  BUNDLED WITH
28
- 2.1.0
46
+ 2.1.4
@@ -42,5 +42,5 @@ end
42
42
  puts("%10s %s" % ["COUNT", "STRING"])
43
43
  counts = b.get_table("counts")
44
44
  counts.items.sort_by{|k, v| v.to_bcc_value }.each do |k, v|
45
- puts("%10d %s" % [v.to_bcc_value, k[0, k.size].unpack("Z*")[0]])
45
+ puts("%10d %s" % [v.to_bcc_value, k.to_bcc_value.c])
46
46
  end
@@ -0,0 +1,155 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Example to use complecated structure in BPF Map key:
4
+ # This program collects and shows raw syscall usage summary.
5
+ #
6
+ # Usage:
7
+ # bundle exec ruby examples/collectsyscall.rb
8
+ #
9
+ # Output example:
10
+ # Collecting syscalls...
11
+ # ^C
12
+ # PID=1098(maybe: gmain) --->
13
+ # inotify_add_watch 4 0.019 ms
14
+ # poll 1 0.000 ms
15
+ #
16
+ # PID=1114(maybe: dbus-daemon) --->
17
+ # stat 12 0.021 ms
18
+ # openat 3 0.015 ms
19
+ # getdents 2 0.013 ms
20
+ # recvmsg 2 0.006 ms
21
+ # sendmsg 1 0.008 ms
22
+ # close 1 0.002 ms
23
+ # fstat 1 0.002 ms
24
+ # epoll_wait 1 0.000 ms
25
+ #
26
+ # PID=1175(maybe: memcached) --->
27
+ # epoll_wait 3 2012.455 ms
28
+ #
29
+ # PID=1213(maybe: redis-server) --->
30
+ # read 64 0.736 ms
31
+ # epoll_wait 32 3782.098 ms
32
+ # openat 32 1.149 ms
33
+ # getpid 32 0.074 ms
34
+ # close 32 0.045 ms
35
+ # ....
36
+
37
+ require 'rbbcc'
38
+ include RbBCC
39
+
40
+ $pid = nil
41
+
42
+ if ARGV.size == 2 &&
43
+ ARGV[0] == '-p'
44
+ $pid = ARGV[1].to_i
45
+ elsif ARGV[0] == '-h' ||
46
+ ARGV[0] == '--help'
47
+ $stderr.puts "Usage: #{$0} [-p PID]"
48
+ exit 1
49
+ end
50
+
51
+ SYSCALL_MAP = `ausyscall --dump`
52
+ .lines
53
+ .map{|l| l.chomp.split }
54
+ .each_with_object(Hash.new) {|(k, v), ha| ha[k.to_i] = v }
55
+
56
+ # if no ausyscall(8) then shows number itself
57
+ # it is included in auditd package (e.g. Ubuntu)
58
+ def to_name(nr)
59
+ SYSCALL_MAP[nr] || nr.to_s
60
+ end
61
+
62
+ prog = <<BPF
63
+ #include <uapi/linux/ptrace.h>
64
+
65
+ struct key_t {
66
+ u32 pid;
67
+ u64 syscall_nr;
68
+ };
69
+ struct leaf_t{
70
+ u64 count;
71
+ u64 elapsed_ns;
72
+ u64 enter_ns;
73
+ char comm[16];
74
+ };
75
+ BPF_HASH(store, struct key_t, struct leaf_t);
76
+
77
+ TRACEPOINT_PROBE(raw_syscalls, sys_enter) {
78
+ struct key_t key = {0};
79
+ struct leaf_t initial = {0}, *val_;
80
+
81
+ key.pid = bpf_get_current_pid_tgid();
82
+ key.syscall_nr = args->id;
83
+
84
+ DO_FILTER_BY_PID
85
+
86
+ val_ = store.lookup_or_try_init(&key, &initial);
87
+ if (val_) {
88
+ struct leaf_t val = *val_;
89
+ val.count++;
90
+ val.enter_ns = bpf_ktime_get_ns();
91
+ bpf_get_current_comm(&val.comm, sizeof(val.comm));
92
+ store.update(&key, &val);
93
+ }
94
+ return 0;
95
+ }
96
+
97
+ TRACEPOINT_PROBE(raw_syscalls, sys_exit) {
98
+ struct key_t key = {0};
99
+ struct leaf_t *val_;
100
+
101
+ key.pid = bpf_get_current_pid_tgid();
102
+ key.syscall_nr = args->id;
103
+
104
+ val_ = store.lookup(&key);
105
+ if (val_) {
106
+ struct leaf_t val = *val_;
107
+ u64 delta = bpf_ktime_get_ns() - val.enter_ns;
108
+ val.enter_ns = 0;
109
+ val.elapsed_ns += delta;
110
+ store.update(&key, &val);
111
+ }
112
+ return 0;
113
+ }
114
+ BPF
115
+
116
+ if $pid
117
+ prog.sub!('DO_FILTER_BY_PID', <<~FILTER)
118
+ if (key.pid != #{$pid}) return 0;
119
+ FILTER
120
+ else
121
+ prog.sub!('DO_FILTER_BY_PID', '')
122
+ end
123
+
124
+ b = BCC.new(text: prog)
125
+
126
+ puts "Collecting syscalls..."
127
+ begin
128
+ sleep(99999999)
129
+ rescue Interrupt
130
+ puts
131
+ end
132
+
133
+ info_by_pids = {}
134
+ comms = {}
135
+ store = b.get_table("store")
136
+ store.items.each do |k, v|
137
+ # require 'pry'; binding.pry
138
+ info_by_pids[k.pid] ||= {}
139
+ info_by_pids[k.pid][k.syscall_nr] = {
140
+ name: to_name(k.syscall_nr),
141
+ count: v.count,
142
+ elapsed_ms: v.elapsed_ns / 1000000.0
143
+ }
144
+ comms[k.pid] ||= v.comm
145
+ end
146
+
147
+ pids = info_by_pids.keys.sort
148
+ pids.each do |pid|
149
+ puts "PID=#{pid}(maybe: #{comms[pid]}) --->"
150
+ i = info_by_pids[pid]
151
+ i.to_a.sort_by {|k, v| [-v[:count], -v[:elapsed_ms]] }.each do |nr, record|
152
+ puts "\t%<name>-20s %<count>3d %<elapsed_ms>8.3f ms" % record
153
+ end
154
+ puts
155
+ end
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # bashreadline Print entered bash commands from all running shells.
4
+ # For Linux, uses BCC, eBPF. Embedded C.
5
+ #
6
+ # USAGE: bashreadline [-s SHARED]
7
+ # This works by tracing the readline() function using a uretprobe (uprobes).
8
+ # When you failed to run the script directly with error:
9
+ # `Exception: could not determine address of symbol b'readline'`,
10
+ # you may need specify the location of libreadline.so library
11
+ # with `-s` option.
12
+ #
13
+ # Original bashreadline.py:
14
+ # Copyright 2016 Netflix, Inc.
15
+ # Licensed under the Apache License, Version 2.0 (the "License")
16
+ # And Ruby version follows.
17
+ #
18
+ # 28-Jan-2016 Brendan Gregg Created bashreadline.py.
19
+ # 12-Feb-2016 Allan McAleavy migrated to BPF_PERF_OUTPUT
20
+ # 05-Jun-2020 Uchio Kondo Ported bashreadline.rb
21
+
22
+ require 'rbbcc'
23
+ require 'optparse'
24
+ include RbBCC
25
+
26
+ args = {}
27
+ opts = OptionParser.new
28
+ opts.on("-s", "--shared=LIBREADLINE_PATH"){|v| args[:shared] = v }
29
+ opts.parse!(ARGV)
30
+
31
+ name = args[:shared] || "/bin/bash"
32
+
33
+ # load BPF program
34
+ bpf_text = <<BPF
35
+ #include <uapi/linux/ptrace.h>
36
+ #include <linux/sched.h>
37
+
38
+ struct str_t {
39
+ u64 pid;
40
+ char str[80];
41
+ };
42
+
43
+ BPF_PERF_OUTPUT(events);
44
+
45
+ int printret(struct pt_regs *ctx) {
46
+ struct str_t data = {};
47
+ char comm[TASK_COMM_LEN] = {};
48
+ u32 pid;
49
+ if (!PT_REGS_RC(ctx))
50
+ return 0;
51
+ pid = bpf_get_current_pid_tgid();
52
+ data.pid = pid;
53
+ bpf_probe_read(&data.str, sizeof(data.str), (void *)PT_REGS_RC(ctx));
54
+
55
+ bpf_get_current_comm(&comm, sizeof(comm));
56
+ if (comm[0] == 'b' && comm[1] == 'a' && comm[2] == 's' && comm[3] == 'h' && comm[4] == 0 ) {
57
+ events.perf_submit(ctx,&data,sizeof(data));
58
+ }
59
+
60
+
61
+ return 0;
62
+ };
63
+ BPF
64
+
65
+ b = BCC.new(text: bpf_text)
66
+ b.attach_uretprobe(name: name, sym: "readline", fn_name: "printret")
67
+
68
+ # header
69
+ puts("%-9s %-6s %s" % ["TIME", "PID", "COMMAND"])
70
+
71
+ b["events"].open_perf_buffer do |cpu, data, size|
72
+ event = b["events"].event(data)
73
+ puts("%-9s %-6d %s" % [
74
+ Time.now.strftime("%H:%M:%S"),
75
+ event.pid,
76
+ event.str
77
+ ])
78
+ end
79
+
80
+ trap(:INT) { puts; exit }
81
+ loop do
82
+ b.perf_buffer_poll
83
+ end
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ if ARGV[0] == '-v' || ARGV[0] == '--version'
4
+ require 'rbbcc/version'
5
+ print "RbBCC: version "
6
+ puts RbBCC::VERSION
7
+ print "Using "
8
+ puts RUBY_DESCRIPTION
9
+ elsif ARGV[0] == '--invoke'
10
+ require 'rbbcc/invoker'
11
+ ARGV.shift
12
+ RbBCC::Invoker.new(ARGV).run
13
+ else
14
+ binpath = File.readlink "/proc/self/exe"
15
+ exec binpath, *ARGV
16
+ end
@@ -1,9 +1,10 @@
1
+ module RbBCC
2
+ autoload :Plugin, 'rbbcc/plugin'
3
+ end
4
+
1
5
  require "rbbcc/fiddle_ext"
2
6
  require "rbbcc/bcc"
3
7
  require "rbbcc/clib"
4
8
  require "rbbcc/usdt"
5
9
  require "rbbcc/symbol_cache"
6
10
  require "rbbcc/version"
7
-
8
- module RbBCC
9
- end
@@ -121,7 +121,6 @@ module RbBCC
121
121
 
122
122
  def decode_table_type(desc)
123
123
  return desc if desc.is_a?(String)
124
-
125
124
  anon = []
126
125
  fields = []
127
126
  # e.g. ["bpf_stacktrace", [["ip", "unsigned long long", [127]]], "struct_packed"]
@@ -153,11 +152,37 @@ module RbBCC
153
152
  raise("Failed to decode type #{field.inspect}")
154
153
  end
155
154
  end
155
+ c = nil
156
156
  if data_type == "union"
157
- return Fiddle::Importer.union(fields)
157
+ c = Fiddle::Importer.union(fields)
158
158
  else
159
- return Fiddle::Importer.struct(fields)
159
+ c = Fiddle::Importer.struct(fields)
160
+ end
161
+
162
+ fields.each do |field|
163
+ md = /^char\[(\d+)\] ([_a-zA-Z0-9]+)/.match(field)
164
+ if md
165
+ c.alias_method "__super_#{md[2]}", md[2]
166
+ c.define_method md[2] do
167
+ # Split the char[] in the place where the first \0 appears
168
+ raw = __send__("__super_#{md[2]}")
169
+ raw = raw[0...raw.index(0)] if raw.index(0)
170
+ raw.pack("c*")
171
+ end
172
+ end
160
173
  end
174
+
175
+ c.define_singleton_method :original_desc do
176
+ desc
177
+ end
178
+ c.define_singleton_method :fields do
179
+ fields
180
+ end
181
+ orig_name = c.inspect
182
+ c.define_singleton_method :inspect do
183
+ orig_name.sub /(?=>$)/, " original_desc=#{desc.inspect}" rescue super
184
+ end
185
+ c
161
186
  end
162
187
 
163
188
  def sym(addr, pid, show_module: false, show_offset: false, demangle: true)
@@ -195,7 +220,7 @@ module RbBCC
195
220
  end
196
221
  end
197
222
 
198
- def initialize(text: "", src_file: nil, hdr_file: nil, debug: 0, cflags: [], usdt_contexts: [], allow_rlimit: 0)
223
+ def initialize(text: "", src_file: nil, hdr_file: nil, debug: 0, cflags: [], usdt_contexts: [], allow_rlimit: 0, dev_name: nil)
199
224
  @kprobe_fds = {}
200
225
  @uprobe_fds = {}
201
226
  @tracepoint_fds = {}
@@ -207,7 +232,7 @@ module RbBCC
207
232
  end
208
233
 
209
234
  if src_file && src_file.end_with?(".b")
210
- @module = Clib.bpf_module_create_b(src_file, hdr_file, debug, device)
235
+ @module = Clib.bpf_module_create_b(src_file, hdr_file, debug, dev_name)
211
236
  else
212
237
  if src_file
213
238
  text = File.read(src_file)
@@ -218,13 +243,20 @@ module RbBCC
218
243
  text = code + text
219
244
  end
220
245
 
221
- # Util.debug text
222
- @module = Clib.bpf_module_create_c_from_string(
246
+
247
+ cflags_safe = if cflags.empty? or !cflags[-1].nil?
248
+ cflags + [nil]
249
+ else
250
+ cflags
251
+ end
252
+
253
+ @module = Clib.do_bpf_module_create_c_from_string(
223
254
  text,
224
255
  debug,
225
- cflags.pack('p*'),
226
- cflags.size,
227
- allow_rlimit
256
+ cflags_safe.pack("p*"),
257
+ cflags_safe.size,
258
+ allow_rlimit,
259
+ dev_name
228
260
  )
229
261
  end
230
262
  @funcs = {}
@@ -25,7 +25,7 @@ module RbBCC
25
25
  end
26
26
 
27
27
  extend Fiddle::Importer
28
- targets = %w(0.14.0 0.13.0 0.12.0 0.11.0 0.10.0)
28
+ targets = %w(0.17.0 0.16.0 0.15.0 0.14.0 0.13.0 0.12.0 0.11.0 0.10.0)
29
29
  if default_load = ENV['LIBBCC_VERSION']
30
30
  targets.unshift(default_load)
31
31
  targets.uniq!
@@ -44,24 +44,38 @@ module RbBCC
44
44
  end
45
45
  typealias "size_t", "int"
46
46
 
47
- extern 'void * bpf_module_create_c_from_string(char *, unsigned int, char **, int, long)'
48
47
  extern 'void * bpf_module_create_b(char *filename, char *proto_filename, unsigned int flags, char *dev_name)'
49
48
  extern 'int bpf_num_functions(void *)'
50
49
  extern 'char * bpf_function_name(void *, int)'
51
50
  extern 'void bpf_module_destroy(void *)'
52
51
 
53
52
  if libbcc_version_gteq?("0.11.0")
53
+ extern 'void * bpf_module_create_c_from_string(
54
+ const char *text, unsigned int flags, const char *cflags[],
55
+ int ncflags, int allow_rlimit,
56
+ const char *dev_name)'
54
57
  extern 'int bcc_func_load(
55
58
  void *program, int prog_type, const char *name,
56
59
  const struct bpf_insn *insns, int prog_len,
57
60
  const char *license, unsigned int kern_version,
58
61
  int log_level, char *log_buf, unsigned int log_buf_size,
59
62
  const char *dev_name)'
63
+ def self.do_bpf_module_create_c_from_string(text, flags, cflags, ncflags, allow_limit, dev_name)
64
+ bpf_module_create_c_from_string(text, flags, cflags, ncflags, allow_limit, dev_name)
65
+ end
66
+
60
67
  def self.do_bcc_func_load(mod, prog_type, name, insns, len, license, kver, loglv, buf, buf_size, device)
61
68
  bcc_func_load(mod, prog_type, name, insns, len, license, kver, loglv, buf, buf_size, device)
62
69
  end
63
70
  else
71
+ extern 'void * bpf_module_create_c_from_string(
72
+ const char *text, unsigned int flags, const char *cflags[],
73
+ int ncflags, int allow_rlimit)'
64
74
  extern 'int bcc_func_load(void *, int, char *, void *, int, char *, unsigned int, int, char *, unsigned int)'
75
+ def self.do_bpf_module_create_c_from_string(text, flags, cflags, ncflags, allow_limit, dev_name=nil)
76
+ bpf_module_create_c_from_string(text, flags, cflags, ncflags, allow_limit)
77
+ end
78
+
65
79
  def self.do_bcc_func_load(mod, prog_type, name, insns, len, license, kver, loglv, buf, buf_size, device)
66
80
  bcc_func_load(mod, prog_type, name, insns, len, license, kver, loglv, buf, buf_size)
67
81
  end
@@ -2,8 +2,17 @@ require 'fiddle'
2
2
  require 'fiddle/import'
3
3
 
4
4
  class Fiddle::Pointer
5
- def to_bcc_value
6
- case self.size
5
+ def bcc_value
6
+ @bcc_value ||= _bcc_value
7
+ end
8
+ alias to_bcc_value bcc_value
9
+
10
+ def _bcc_value
11
+ if self.bcc_value_type.is_a?(Class)
12
+ return self.bcc_value_type.new(self)
13
+ end
14
+
15
+ case self.bcc_size
7
16
  when Fiddle::Importer.sizeof("int")
8
17
  self[0, self.size].unpack("i!").first
9
18
  when Fiddle::Importer.sizeof("long")
@@ -12,4 +21,27 @@ class Fiddle::Pointer
12
21
  self[0, self.size].unpack("Z*").first
13
22
  end
14
23
  end
24
+
25
+ def method_missing(name, *a)
26
+ fields = \
27
+ if self.respond_to?(:bcc_value_type) && \
28
+ self.bcc_value_type.respond_to?(:fields)
29
+ self.bcc_value_type.fields.map{|v| v.split.last.to_sym }
30
+ else
31
+ nil
32
+ end
33
+ return super unless fields
34
+
35
+ if fields.include?(name) && bcc_value.respond_to?(name)
36
+ bcc_value.send(name)
37
+ else
38
+ super
39
+ end
40
+ end
41
+
42
+ attr_accessor :bcc_value_type
43
+ attr_writer :bcc_size
44
+ def bcc_size
45
+ @bcc_size || self.size
46
+ end
15
47
  end
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'rbbcc/plugin'
3
+
4
+ module RbBCC
5
+ class Invoker
6
+ def initialize(args)
7
+ @command = args.shift
8
+ raise "Invalid option. Please specify script name" unless @command
9
+
10
+ args.shift if args[0] == '--'
11
+ @args = args
12
+ end
13
+
14
+ def run
15
+ plugins = Gem::Specification
16
+ .find_all
17
+ .select{|s| s.name =~ /^rbbcc-/ }
18
+ .map(&:name)
19
+ plugins.each {|n| require n }
20
+
21
+ script = RbBCC::Plugin.find_script_name(@command)
22
+ raise Errno::ENOENT, "Script not found: #{@command}" unless script
23
+
24
+ binpath = File.readlink "/proc/self/exe"
25
+ Process.exec binpath, script, *@args
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ module RbBCC
2
+ module Plugin
3
+ ScriptLocation = Struct.new(:name, :location)
4
+
5
+ def self.scripts
6
+ @scripts ||= []
7
+ end
8
+
9
+ def self.find_script_name(name)
10
+ scripts.find{|s|
11
+ s.name == name || "#{s.name}.rb" == name
12
+ }&.location
13
+ end
14
+
15
+ def self.register!
16
+ caller_loc = caller[0].split(':')[0]
17
+ plugin_loc = File.expand_path("../../script", caller_loc)
18
+ unless File.directory?(plugin_loc)
19
+ raise "Cannot find a script directory #{plugin_loc}. Maybe an invalid project"
20
+ end
21
+
22
+ found = Dir.glob("#{plugin_loc}/*.rb")
23
+ .map{|path| ScriptLocation.new File.basename(path, '.rb'), path }
24
+ self.scripts.concat found
25
+ self.scripts
26
+ end
27
+ end
28
+ end
@@ -50,12 +50,13 @@ module RbBCC
50
50
  def initialize(bpf, map_id, map_fd, keytype, leaftype, name: nil)
51
51
  @bpf, @map_id, @map_fd, @keysize, @leafsize = \
52
52
  bpf, map_id, map_fd, sizeof(keytype), sizeof(leaftype)
53
+ @keytype = keytype
53
54
  @leaftype = leaftype
54
55
  @ttype = Clib.bpf_table_type_id(self.bpf.module, self.map_id)
55
56
  @flags = Clib.bpf_table_flags_id(self.bpf.module, self.map_id)
56
57
  @name = name
57
58
  end
58
- attr_reader :bpf, :map_id, :map_fd, :keysize, :leafsize, :leaftype, :ttype, :flags, :name
59
+ attr_reader :bpf, :map_id, :map_fd, :keysize, :keytype, :leafsize, :leaftype, :ttype, :flags, :name
59
60
 
60
61
  def next(key)
61
62
  next_key = Fiddle::Pointer.malloc(self.keysize)
@@ -86,6 +87,7 @@ module RbBCC
86
87
  if res < 0
87
88
  nil
88
89
  end
90
+ leaf.bcc_value_type = leaftype
89
91
  return leaf
90
92
  end
91
93
 
@@ -93,8 +95,9 @@ module RbBCC
93
95
  self[key] || raise(KeyError, "key not found")
94
96
  end
95
97
 
96
- def []=(_key, leaf)
98
+ def []=(_key, _leaf)
97
99
  key = normalize_key(_key)
100
+ leaf = normalize_leaf(_leaf)
98
101
  res = Clib.bpf_update_elem(self.map_fd, key, leaf, 0)
99
102
  if res < 0
100
103
  raise SystemCallError.new("Could not update table", Fiddle.last_error)
@@ -186,11 +189,29 @@ module RbBCC
186
189
  def normalize_key(key)
187
190
  case key
188
191
  when Fiddle::Pointer
192
+ key.bcc_value_type = keytype
193
+ key.bcc_size = keysize
189
194
  key
190
195
  when Integer
191
- byref(key, keysize)
196
+ ret = byref(key, keysize)
197
+ ret.bcc_value_type = keytype
198
+ ret
192
199
  else
193
- raise KeyError, "#{key.inspect} must be integer or pointor"
200
+ raise ArgumentError, "#{key.inspect} must be integer or pointor"
201
+ end
202
+ end
203
+
204
+ def normalize_leaf(leaf)
205
+ case leaf
206
+ when Fiddle::Pointer
207
+ leaf.bcc_value_type = leaftype
208
+ leaf
209
+ when Integer
210
+ ret = byref(leaf, keysize)
211
+ ret.bcc_value_type = leaftype
212
+ ret
213
+ else
214
+ raise KeyError, "#{leaf.inspect} must be integer or pointor"
194
215
  end
195
216
  end
196
217
 
@@ -202,6 +223,7 @@ module RbBCC
202
223
  end
203
224
  ptr = Fiddle::Pointer.malloc(size)
204
225
  ptr[0, size] = [value].pack(pack_fmt)
226
+ ptr.bcc_size = size
205
227
  ptr
206
228
  end
207
229
  end
@@ -1,3 +1,3 @@
1
1
  module RbBCC
2
- VERSION = "0.5.0"
2
+ VERSION = "0.6.4"
3
3
  end
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
19
19
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
20
  end
21
- #spec.bindir = "exe"
22
- #spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.bindir = "exe"
22
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
23
23
  spec.require_paths = ["lib"]
24
24
  end
metadata CHANGED
@@ -1,19 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbbcc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Uchio Kondo
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2020-06-05 00:00:00.000000000 Z
11
+ date: 2020-11-26 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: BCC port for MRI. See https://github.com/iovisor/bcc
14
14
  email:
15
15
  - udzura@udzura.jp
16
- executables: []
16
+ executables:
17
+ - rbbcc
17
18
  extensions: []
18
19
  extra_rdoc_files: []
19
20
  files:
@@ -56,6 +57,7 @@ files:
56
57
  - examples/charty/Gemfile
57
58
  - examples/charty/Gemfile.lock
58
59
  - examples/charty/bitehist-unicode.rb
60
+ - examples/collectsyscall.rb
59
61
  - examples/dddos.rb
60
62
  - examples/disksnoop.rb
61
63
  - examples/example.gif
@@ -69,12 +71,14 @@ files:
69
71
  - examples/networking/http_filter/http-parse-simple.rb
70
72
  - examples/ruby_usdt.rb
71
73
  - examples/sbrk_trace.rb
74
+ - examples/tools/bashreadline.rb
72
75
  - examples/tools/execsnoop.rb
73
76
  - examples/tools/runqlat.rb
74
77
  - examples/urandomread-explicit.rb
75
78
  - examples/urandomread.rb
76
79
  - examples/usdt-test.rb
77
80
  - examples/usdt.rb
81
+ - exe/rbbcc
78
82
  - lib/rbbcc.rb
79
83
  - lib/rbbcc/bcc.rb
80
84
  - lib/rbbcc/clib.rb
@@ -83,6 +87,8 @@ files:
83
87
  - lib/rbbcc/debug.rb
84
88
  - lib/rbbcc/disp_helper.rb
85
89
  - lib/rbbcc/fiddle_ext.rb
90
+ - lib/rbbcc/invoker.rb
91
+ - lib/rbbcc/plugin.rb
86
92
  - lib/rbbcc/symbol_cache.rb
87
93
  - lib/rbbcc/table.rb
88
94
  - lib/rbbcc/usdt.rb
@@ -109,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
115
  - !ruby/object:Gem::Version
110
116
  version: '0'
111
117
  requirements: []
112
- rubygems_version: 3.0.3
118
+ rubygems_version: 3.1.2
113
119
  signing_key:
114
120
  specification_version: 4
115
121
  summary: BCC port for MRI