rbbcc 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/examples/ruby_usdt.rb +105 -0
- data/examples/sbrk_trace.rb +204 -0
- data/lib/rbbcc/bcc.rb +9 -7
- data/lib/rbbcc/clib.rb +2 -1
- data/lib/rbbcc/debug.rb +17 -0
- data/lib/rbbcc/usdt.rb +21 -4
- data/lib/rbbcc/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 403f2664a61a40bce19ee3ca85f9637822b2172fb8123e7758f49342e022725f
|
4
|
+
data.tar.gz: 81f005eeb8d5c53faedffe8b01874b952faff8d81cda3b5319bc3fdde0044d6d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ea74e38ea3bf6668c6d17b2907e7fe08497c913eff17776b77194cbb2285a79b9259f6412564ae5ec16c4979a321abcdf299d7735f363c5304ce0f665465e09
|
7
|
+
data.tar.gz: 46e964f12ddce367941db82c6efd33dbcf0ad6c396b51e39c4ea0e2ebc26dd0568558ebc44794144104f0b30def56d5ebae7173a9fe78fa883e7579226a0f588
|
data/Gemfile.lock
CHANGED
@@ -0,0 +1,105 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# To run this example, please build the target ruby with an `--enable-dtrace` option in advance.
|
3
|
+
# To build via rbenv, sample command is:
|
4
|
+
# $ RUBY_CONFIGURE_OPTS='--enable-dtrace' rbenv install 2.7.0
|
5
|
+
#
|
6
|
+
# Example autput:
|
7
|
+
# # bundle exec ruby examples/ruby_usdt.rb $(pidof irb)
|
8
|
+
# TIME(s) COMM KLASS PATH
|
9
|
+
# 0.000000000 irb Struct::Key /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/reline.rb
|
10
|
+
# 0.000055206 irb Array /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/reline/line_editor.rb
|
11
|
+
# 0.000088588 irb Ripper::Lexer /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/ripper/lexer.rb
|
12
|
+
# 0.000117740 irb Ripper::Lexer::Elem /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/ripper/lexer.rb
|
13
|
+
# 0.000126697 irb Ripper::Lexer::State /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/ripper/lexer.rb
|
14
|
+
# 0.000213388 irb Array /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/reline/line_editor.rb
|
15
|
+
# 0.000225678 irb Ripper::Lexer /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/ripper/lexer.rb
|
16
|
+
# 0.000243638 irb Array /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/reline/line_editor.rb
|
17
|
+
# 0.000254680 irb Range /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/irb/ruby-lex.rb
|
18
|
+
# 0.000264707 irb Ripper::Lexer /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/ripper/lexer.rb
|
19
|
+
# 0.000275579 irb Ripper::Lexer::Elem /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/ripper/lexer.rb
|
20
|
+
# 0.000282438 irb Ripper::Lexer::State /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/ripper/lexer.rb
|
21
|
+
# 0.000326136 irb String /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/irb.rb
|
22
|
+
# 0.001353621 irb Array /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/reline/line_editor.rb
|
23
|
+
# 0.001385320 irb IRB::Color::SymbolState /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/irb/color.rb
|
24
|
+
# 0.001397043 irb Ripper::Lexer /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/irb/color.rb
|
25
|
+
# 0.001416420 irb Ripper::Lexer::Elem /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/ripper/lexer.rb
|
26
|
+
# 0.001423861 irb Ripper::Lexer::State /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/ripper/lexer.rb
|
27
|
+
# 0.001462010 irb Ripper::Lexer::State /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/ripper/lexer.rb
|
28
|
+
# 0.001478995 irb Array /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/reline/line_editor.rb
|
29
|
+
# 0.001487499 irb Range /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/irb/ruby-lex.rb
|
30
|
+
# 0.001496666 irb Ripper::Lexer /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/ripper/lexer.rb
|
31
|
+
# 0.001508224 irb Ripper::Lexer::Elem /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/ripper/lexer.rb
|
32
|
+
# 0.001515143 irb Ripper::Lexer::State /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/ripper/lexer.rb
|
33
|
+
# 0.001556170 irb String /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/irb.rb
|
34
|
+
# 0.001726273 irb String /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/reline/line_editor.rb
|
35
|
+
# 0.001946948 irb Array /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/reline/line_editor.rb
|
36
|
+
# 0.001956585 irb String /root/.rbenv/versions/2.7.0/lib/ruby/2.7.0/reline.rb
|
37
|
+
|
38
|
+
require 'rbbcc'
|
39
|
+
include RbBCC
|
40
|
+
|
41
|
+
pid = ARGV[0] || begin
|
42
|
+
puts("USAGE: #{$0} PID")
|
43
|
+
exit()
|
44
|
+
end
|
45
|
+
debug = !!ENV['DEBUG']
|
46
|
+
|
47
|
+
bpf_text = <<BPF
|
48
|
+
#include <uapi/linux/ptrace.h>
|
49
|
+
#include <linux/sched.h>
|
50
|
+
|
51
|
+
struct data_t {
|
52
|
+
u64 ts;
|
53
|
+
char comm[TASK_COMM_LEN];
|
54
|
+
char klass[64];
|
55
|
+
char path[256];
|
56
|
+
};
|
57
|
+
BPF_PERF_OUTPUT(events);
|
58
|
+
|
59
|
+
int do_trace_create_object(struct pt_regs *ctx) {
|
60
|
+
struct data_t data = {};
|
61
|
+
uint64_t addr, addr2;
|
62
|
+
|
63
|
+
data.ts = bpf_ktime_get_ns();
|
64
|
+
|
65
|
+
bpf_get_current_comm(&data.comm, sizeof(data.comm));
|
66
|
+
bpf_usdt_readarg_p(1, ctx, &data.klass, sizeof(data.klass));
|
67
|
+
bpf_usdt_readarg_p(2, ctx, &data.path, sizeof(data.path));
|
68
|
+
|
69
|
+
events.perf_submit(ctx, &data, sizeof(data));
|
70
|
+
|
71
|
+
return 0;
|
72
|
+
};
|
73
|
+
BPF
|
74
|
+
|
75
|
+
u = USDT.new(pid: pid.to_i)
|
76
|
+
u.enable_probe(probe: "object__create", fn_name: "do_trace_create_object")
|
77
|
+
if debug
|
78
|
+
puts(u.get_text)
|
79
|
+
puts(bpf_text)
|
80
|
+
end
|
81
|
+
|
82
|
+
# initialize BPF
|
83
|
+
b = BCC.new(text: bpf_text, usdt_contexts: [u])
|
84
|
+
|
85
|
+
puts("%-18s %-6s %-24s %s" % ["TIME(s)", "COMM", "KLASS", "PATH"])
|
86
|
+
|
87
|
+
# process event
|
88
|
+
start = 0
|
89
|
+
b["events"].open_perf_buffer do |cpu, data, size|
|
90
|
+
event = b["events"].event(data)
|
91
|
+
if start == 0
|
92
|
+
start = event.ts
|
93
|
+
end
|
94
|
+
|
95
|
+
time_s = ((event.ts - start).to_f) / 1000000000
|
96
|
+
puts(
|
97
|
+
"%-18.9f %-6s %-24s %s" %
|
98
|
+
[time_s, event.comm, event.klass, event.path]
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
Signal.trap(:INT) { puts "\nDone."; exit }
|
103
|
+
loop do
|
104
|
+
b.perf_buffer_poll()
|
105
|
+
end
|
@@ -0,0 +1,204 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Trace example for libc's USDT:
|
3
|
+
# - memory_sbrk_more
|
4
|
+
# - memory_sbrk_less
|
5
|
+
# - memory_mallopt_free_dyn_thresholds
|
6
|
+
# Description is here: https://www.gnu.org/software/libc/manual/html_node/Memory-Allocation-Probes.html
|
7
|
+
#
|
8
|
+
# Example output:
|
9
|
+
# bundle exec ruby examples/sbrk_trace.rb -c ruby
|
10
|
+
# !! Trace start.
|
11
|
+
# [ 0.000000000] pid=32756 comm=ruby probe=memory_sbrk_more addr=0x55f34b979000 size=135168
|
12
|
+
# [ 0.036549804] pid=32756 comm=ruby probe=memory_sbrk_more addr=0x557fd9760000 size=135168
|
13
|
+
# [ 0.036804183] pid=32756 comm=ruby probe=memory_sbrk_more addr=0x557fd9781000 size=143360
|
14
|
+
# [ 0.036855378] pid=32756 comm=ruby probe=memory_sbrk_less addr=0x557fd97a0000 size=16384
|
15
|
+
# [ 0.036931376] pid=32756 comm=ruby probe=memory_sbrk_more addr=0x557fd97a0000 size=147456
|
16
|
+
# [ 0.036940382] pid=32756 comm=ruby probe=memory_sbrk_less addr=0x557fd97c0000 size=16384
|
17
|
+
# [ 0.037022971] pid=32756 comm=ruby probe=memory_sbrk_more addr=0x557fd97c0000 size=151552
|
18
|
+
# [ 0.038602464] pid=32756 comm=ruby probe=memory_sbrk_more addr=0x557fd97e5000 size=204800
|
19
|
+
# [ 0.039398297] pid=32756 comm=ruby probe=memory_sbrk_more addr=0x557fd9817000 size=135168
|
20
|
+
# [ 0.039909594] pid=32756 comm=ruby probe=memory_sbrk_more addr=0x557fd9838000 size=135168
|
21
|
+
# [ 0.040536005] pid=32756 comm=ruby probe=memory_sbrk_more addr=0x557fd9859000 size=163840
|
22
|
+
# ...
|
23
|
+
|
24
|
+
require 'rbbcc'
|
25
|
+
include RbBCC
|
26
|
+
|
27
|
+
def usage
|
28
|
+
puts("USAGE: #{$0} [-p PID|-c COMM]")
|
29
|
+
exit()
|
30
|
+
end
|
31
|
+
|
32
|
+
def find_libc_location
|
33
|
+
if File.exist?('/lib/x86_64-linux-gnu/libc.so.6')
|
34
|
+
'/lib/x86_64-linux-gnu/libc.so.6'
|
35
|
+
else
|
36
|
+
`find /lib -name 'libc.so*' | grep -v musl | head -1`.chomp
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
usage if ARGV.size != 0 && ARGV.size != 2
|
41
|
+
|
42
|
+
pid = comm = nil
|
43
|
+
path = find_libc_location
|
44
|
+
case ARGV[0]
|
45
|
+
when '-p', '--pid'
|
46
|
+
pid = ARGV[1].to_i
|
47
|
+
when '-c', '--comm'
|
48
|
+
comm = ARGV[1]
|
49
|
+
when nil
|
50
|
+
# nop
|
51
|
+
else
|
52
|
+
usage
|
53
|
+
end
|
54
|
+
|
55
|
+
debug = !!ENV['DEBUG']
|
56
|
+
|
57
|
+
bpf_text = <<BPF
|
58
|
+
#include <uapi/linux/ptrace.h>
|
59
|
+
#include <linux/sched.h>
|
60
|
+
|
61
|
+
struct data_t {
|
62
|
+
u32 type;
|
63
|
+
u64 ts;
|
64
|
+
u32 pid;
|
65
|
+
char comm[TASK_COMM_LEN];
|
66
|
+
u64 addr;
|
67
|
+
u32 sbrk_size;
|
68
|
+
u32 adjusted_mmap;
|
69
|
+
u32 trim_thresholds;
|
70
|
+
};
|
71
|
+
BPF_PERF_OUTPUT(events);
|
72
|
+
|
73
|
+
static inline bool streq(uintptr_t str) {
|
74
|
+
char needle[] = "{{NEEDLE}}";
|
75
|
+
char haystack[sizeof(needle)];
|
76
|
+
bpf_probe_read(&haystack, sizeof(haystack), (void *)str);
|
77
|
+
for (int i = 0; i < sizeof(needle) - 1; ++i) {
|
78
|
+
if (needle[i] != haystack[i]) {
|
79
|
+
return false;
|
80
|
+
}
|
81
|
+
}
|
82
|
+
return true;
|
83
|
+
}
|
84
|
+
|
85
|
+
#define PROBE_TYPE_more 1
|
86
|
+
#define PROBE_TYPE_less 2
|
87
|
+
#define PROBE_TYPE_free 3
|
88
|
+
|
89
|
+
{{FUNC_MORE}}
|
90
|
+
|
91
|
+
{{FUNC_LESS}}
|
92
|
+
|
93
|
+
int trace_memory_free(struct pt_regs *ctx) {
|
94
|
+
struct data_t data = {};
|
95
|
+
long buf;
|
96
|
+
|
97
|
+
data.type = PROBE_TYPE_free;
|
98
|
+
data.ts = bpf_ktime_get_ns();
|
99
|
+
data.pid = bpf_get_current_pid_tgid();
|
100
|
+
bpf_get_current_comm(&data.comm, sizeof(data.comm));
|
101
|
+
|
102
|
+
{{NEEDLE_START}}
|
103
|
+
bpf_usdt_readarg(1, ctx, &buf);
|
104
|
+
data.adjusted_mmap = buf;
|
105
|
+
|
106
|
+
bpf_usdt_readarg(2, ctx, &buf);
|
107
|
+
data.trim_thresholds = buf;
|
108
|
+
|
109
|
+
events.perf_submit(ctx, &data, sizeof(data));
|
110
|
+
{{NEEDLE_END}}
|
111
|
+
|
112
|
+
return 0;
|
113
|
+
};
|
114
|
+
|
115
|
+
BPF
|
116
|
+
|
117
|
+
trace_fun_sbrk = <<FUNC
|
118
|
+
int trace_memory_sbrk_{{TYPE}}(struct pt_regs *ctx) {
|
119
|
+
struct data_t data = {};
|
120
|
+
long buf;
|
121
|
+
|
122
|
+
data.type = PROBE_TYPE_{{TYPE}};
|
123
|
+
data.ts = bpf_ktime_get_ns();
|
124
|
+
data.pid = bpf_get_current_pid_tgid();
|
125
|
+
bpf_get_current_comm(&data.comm, sizeof(data.comm));
|
126
|
+
|
127
|
+
{{NEEDLE_START}}
|
128
|
+
bpf_usdt_readarg(1, ctx, &buf);
|
129
|
+
data.addr = buf;
|
130
|
+
|
131
|
+
bpf_usdt_readarg(2, ctx, &buf);
|
132
|
+
data.sbrk_size = buf;
|
133
|
+
|
134
|
+
events.perf_submit(ctx, &data, sizeof(data));
|
135
|
+
{{NEEDLE_END}}
|
136
|
+
|
137
|
+
return 0;
|
138
|
+
};
|
139
|
+
FUNC
|
140
|
+
|
141
|
+
PROBE_TYPE_more = 1
|
142
|
+
PROBE_TYPE_less = 2
|
143
|
+
PROBE_TYPE_free = 3
|
144
|
+
PROBE_MAP = {
|
145
|
+
PROBE_TYPE_more => 'memory_sbrk_more',
|
146
|
+
PROBE_TYPE_less => 'memory_sbrk_less',
|
147
|
+
PROBE_TYPE_free => 'memory_mallopt_free_dyn_thresholds'
|
148
|
+
}
|
149
|
+
|
150
|
+
bpf_text.sub!('{{FUNC_MORE}}', trace_fun_sbrk.gsub('{{TYPE}}', 'more'))
|
151
|
+
bpf_text.sub!('{{FUNC_LESS}}', trace_fun_sbrk.gsub('{{TYPE}}', 'less'))
|
152
|
+
|
153
|
+
if comm
|
154
|
+
bpf_text.sub!('{{NEEDLE}}', comm)
|
155
|
+
bpf_text.gsub!('{{NEEDLE_START}}', "if(streq((uintptr_t)data.comm)) {")
|
156
|
+
bpf_text.gsub!('{{NEEDLE_END}}', "}")
|
157
|
+
else
|
158
|
+
bpf_text.sub!('{{NEEDLE}}', "")
|
159
|
+
bpf_text.gsub!('{{NEEDLE_START}}', "")
|
160
|
+
bpf_text.gsub!('{{NEEDLE_END}}', "")
|
161
|
+
end
|
162
|
+
|
163
|
+
u = USDT.new(pid: pid, path: path)
|
164
|
+
u.enable_probe(probe: "memory_sbrk_more", fn_name: "trace_memory_sbrk_more")
|
165
|
+
u.enable_probe(probe: "memory_sbrk_less", fn_name: "trace_memory_sbrk_less")
|
166
|
+
if pid
|
167
|
+
# FIXME: Only available when PID is specified
|
168
|
+
# otherwise got an error:
|
169
|
+
# bpf: Failed to load program: Invalid argument
|
170
|
+
# last insn is not an exit or jmp
|
171
|
+
# It seems libbcc won't generate proper readarg helper
|
172
|
+
u.enable_probe(probe: "memory_mallopt_free_dyn_thresholds", fn_name: "trace_memory_free")
|
173
|
+
end
|
174
|
+
|
175
|
+
# initialize BPF
|
176
|
+
b = BCC.new(text: bpf_text, usdt_contexts: [u])
|
177
|
+
|
178
|
+
puts "!! Trace start."
|
179
|
+
# process event
|
180
|
+
start = 0
|
181
|
+
b["events"].open_perf_buffer do |cpu, data, size|
|
182
|
+
event = b["events"].event(data)
|
183
|
+
if start == 0
|
184
|
+
start = event.ts
|
185
|
+
end
|
186
|
+
|
187
|
+
time_s = ((event.ts - start).to_f) / 1000000000
|
188
|
+
if [PROBE_TYPE_more, PROBE_TYPE_less].include?(event.type)
|
189
|
+
puts(
|
190
|
+
"[%18.9f] pid=%d comm=%s probe=%s addr=%#x size=%d" %
|
191
|
+
[time_s, event.pid, event.comm, PROBE_MAP[event.type], event.addr, event.sbrk_size]
|
192
|
+
)
|
193
|
+
else
|
194
|
+
puts(
|
195
|
+
"[%18.9f] pid=%d comm=%s probe=%s adjusted_mmap=%d trim_thresholds=%d" %
|
196
|
+
[time_s, event.pid, event.comm, PROBE_MAP[event.type], event.adjusted_mmap, event.trim_thresholds]
|
197
|
+
)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
Signal.trap(:INT) { puts "\n!! Done."; exit }
|
202
|
+
loop do
|
203
|
+
b.perf_buffer_poll()
|
204
|
+
end
|
data/lib/rbbcc/bcc.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rbbcc/consts'
|
2
2
|
require 'rbbcc/table'
|
3
3
|
require 'rbbcc/symbol_cache'
|
4
|
+
require 'rbbcc/debug'
|
4
5
|
|
5
6
|
module RbBCC
|
6
7
|
SYSCALL_PREFIXES = [
|
@@ -217,6 +218,7 @@ module RbBCC
|
|
217
218
|
text = code + text
|
218
219
|
end
|
219
220
|
|
221
|
+
# Util.debug text
|
220
222
|
@module = Clib.bpf_module_create_c_from_string(
|
221
223
|
text,
|
222
224
|
debug,
|
@@ -282,7 +284,7 @@ module RbBCC
|
|
282
284
|
if fd < 0
|
283
285
|
raise SystemCallError.new("Failed to attach BPF program #{fn_name} to tracepoint #{tp}", Fiddle.last_error)
|
284
286
|
end
|
285
|
-
|
287
|
+
Util.debug "Attach: #{tp}"
|
286
288
|
@tracepoint_fds[tp] = fd
|
287
289
|
self
|
288
290
|
end
|
@@ -297,7 +299,7 @@ module RbBCC
|
|
297
299
|
if fd < 0
|
298
300
|
raise SystemCallError.new("Failed to attach BPF program #{fn_name} to raw tracepoint #{tp}", Fiddle.last_error)
|
299
301
|
end
|
300
|
-
|
302
|
+
Util.debug "Attach: #{tp}"
|
301
303
|
@raw_tracepoint_fds[tp] = fd
|
302
304
|
self
|
303
305
|
end
|
@@ -309,7 +311,7 @@ module RbBCC
|
|
309
311
|
if fd < 0
|
310
312
|
raise SystemCallError.new("Failed to attach BPF program #{fn_name} to kprobe #{event}", Fiddle.last_error)
|
311
313
|
end
|
312
|
-
|
314
|
+
Util.debug "Attach: #{ev_name}"
|
313
315
|
@kprobe_fds[ev_name] = fd
|
314
316
|
[ev_name, fd]
|
315
317
|
end
|
@@ -322,7 +324,7 @@ module RbBCC
|
|
322
324
|
if fd < 0
|
323
325
|
raise SystemCallError.new("Failed to attach BPF program #{fn_name} to kretprobe #{event}", Fiddle.last_error)
|
324
326
|
end
|
325
|
-
|
327
|
+
Util.debug "Attach: #{ev_name}"
|
326
328
|
@kprobe_fds[ev_name] = fd
|
327
329
|
[ev_name, fd]
|
328
330
|
end
|
@@ -336,7 +338,7 @@ module RbBCC
|
|
336
338
|
if fd < 0
|
337
339
|
raise SystemCallError.new(Fiddle.last_error)
|
338
340
|
end
|
339
|
-
|
341
|
+
Util.debug "Attach: #{ev_name}"
|
340
342
|
|
341
343
|
@uprobe_fds[ev_name] = fd
|
342
344
|
[ev_name, fd]
|
@@ -351,7 +353,7 @@ module RbBCC
|
|
351
353
|
if fd < 0
|
352
354
|
raise SystemCallError.new(Fiddle.last_error)
|
353
355
|
end
|
354
|
-
|
356
|
+
Util.debug "Attach: #{ev_name}"
|
355
357
|
|
356
358
|
@uprobe_fds[ev_name] = fd
|
357
359
|
[ev_name, fd]
|
@@ -552,7 +554,7 @@ module RbBCC
|
|
552
554
|
else
|
553
555
|
next
|
554
556
|
end
|
555
|
-
|
557
|
+
Util.debug "Found fnc: #{func_name}"
|
556
558
|
if func_name.start_with?("kprobe__")
|
557
559
|
fn = load_func(func_name, BPF::KPROBE)
|
558
560
|
attach_kprobe(
|
data/lib/rbbcc/clib.rb
CHANGED
@@ -120,10 +120,11 @@ module RbBCC
|
|
120
120
|
extern 'char * bpf_perf_event_field(void *program, const char *event, size_t i)'
|
121
121
|
|
122
122
|
extern 'void * bcc_usdt_new_frompid(int, char *)'
|
123
|
+
extern 'void * bcc_usdt_new_frompath(char *path)'
|
123
124
|
extern 'int bcc_usdt_enable_probe(void *, char *, char *)'
|
124
125
|
extern 'char * bcc_usdt_genargs(void **, int)'
|
125
126
|
extern 'void bcc_usdt_foreach_uprobe(void *, void *)'
|
126
|
-
|
127
|
+
extern 'void bcc_usdt_close(void *usdt)'
|
127
128
|
BCCSymbol = struct([
|
128
129
|
"const char *name",
|
129
130
|
"const char *demangle_name",
|
data/lib/rbbcc/debug.rb
ADDED
data/lib/rbbcc/usdt.rb
CHANGED
@@ -4,15 +4,21 @@ module RbBCC
|
|
4
4
|
USDTProbe = Struct.new(:binpath, :fn_name, :addr, :pid)
|
5
5
|
|
6
6
|
class USDT
|
7
|
-
|
8
|
-
def initialize(pid:)
|
7
|
+
def initialize(pid: nil, path: nil)
|
9
8
|
@pid = pid
|
10
|
-
@
|
9
|
+
@path = path
|
10
|
+
if pid
|
11
|
+
@context = Clib.bcc_usdt_new_frompid(pid, path)
|
12
|
+
elsif path
|
13
|
+
@context = Clib.bcc_usdt_new_frompath(path)
|
14
|
+
else
|
15
|
+
raise "Either a pid or a binary path must be specified"
|
16
|
+
end
|
11
17
|
if !@context || @context.null?
|
12
18
|
raise SystemCallError.new(Fiddle.last_error)
|
13
19
|
end
|
14
20
|
end
|
15
|
-
attr_reader :pid, :context
|
21
|
+
attr_reader :pid, :path, :context
|
16
22
|
|
17
23
|
def enable_probe(probe:, fn_name:)
|
18
24
|
ret = Clib.bcc_usdt_enable_probe(@context, probe, fn_name)
|
@@ -33,5 +39,16 @@ module RbBCC
|
|
33
39
|
|
34
40
|
return probes
|
35
41
|
end
|
42
|
+
|
43
|
+
private
|
44
|
+
def __del__
|
45
|
+
lambda { Clib.bcc_usdt_close(@context); Util.debug("USDT GC'ed.") }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
at_exit do
|
51
|
+
ObjectSpace.each_object(RbBCC::USDT) do |o|
|
52
|
+
o.send(:__del__).call
|
36
53
|
end
|
37
54
|
end
|
data/lib/rbbcc/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbbcc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Uchio Kondo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-03-
|
11
|
+
date: 2020-03-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -123,6 +123,8 @@ files:
|
|
123
123
|
- examples/mallocstack.rb
|
124
124
|
- examples/networking/http_filter/http-parse-simple.c
|
125
125
|
- examples/networking/http_filter/http-parse-simple.rb
|
126
|
+
- examples/ruby_usdt.rb
|
127
|
+
- examples/sbrk_trace.rb
|
126
128
|
- examples/tools/execsnoop.rb
|
127
129
|
- examples/tools/runqlat.rb
|
128
130
|
- examples/urandomread-explicit.rb
|
@@ -134,6 +136,7 @@ files:
|
|
134
136
|
- lib/rbbcc/clib.rb
|
135
137
|
- lib/rbbcc/consts.rb
|
136
138
|
- lib/rbbcc/cpu_helper.rb
|
139
|
+
- lib/rbbcc/debug.rb
|
137
140
|
- lib/rbbcc/disp_helper.rb
|
138
141
|
- lib/rbbcc/fiddle_ext.rb
|
139
142
|
- lib/rbbcc/symbol_cache.rb
|