pf2 0.5.2 → 0.7.0
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/CHANGELOG.md +20 -0
- data/Cargo.lock +7 -27
- data/README.md +1 -1
- data/crates/backtrace-sys2/build.rs +1 -4
- data/crates/backtrace-sys2/src/libbacktrace/Makefile.am +116 -31
- data/crates/backtrace-sys2/src/libbacktrace/Makefile.in +295 -141
- data/crates/backtrace-sys2/src/libbacktrace/README.md +11 -1
- data/crates/backtrace-sys2/src/libbacktrace/alloc.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/allocfail.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/allocfail.sh +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/atomic.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/backtrace-supported.h.in +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/backtrace.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/backtrace.h +12 -12
- data/crates/backtrace-sys2/src/libbacktrace/btest.c +24 -8
- data/crates/backtrace-sys2/src/libbacktrace/config/libtool.m4 +162 -53
- data/crates/backtrace-sys2/src/libbacktrace/config.h.in +3 -0
- data/crates/backtrace-sys2/src/libbacktrace/configure +255 -66
- data/crates/backtrace-sys2/src/libbacktrace/configure.ac +27 -8
- data/crates/backtrace-sys2/src/libbacktrace/dwarf.c +37 -30
- data/crates/backtrace-sys2/src/libbacktrace/edtest.c +2 -2
- data/crates/backtrace-sys2/src/libbacktrace/edtest2.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/elf.c +98 -76
- data/crates/backtrace-sys2/src/libbacktrace/fileline.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/install-debuginfo-for-buildid.sh.in +2 -2
- data/crates/backtrace-sys2/src/libbacktrace/instrumented_alloc.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/internal.h +41 -2
- data/crates/backtrace-sys2/src/libbacktrace/macho.c +25 -19
- data/crates/backtrace-sys2/src/libbacktrace/mmap.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/mmapio.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/mtest.c +4 -4
- data/crates/backtrace-sys2/src/libbacktrace/nounwind.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/pecoff.c +192 -26
- data/crates/backtrace-sys2/src/libbacktrace/posix.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/print.c +41 -16
- data/crates/backtrace-sys2/src/libbacktrace/read.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/simple.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/sort.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/state.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/stest.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/test_format.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/testlib.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/testlib.h +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/ttest.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/unittest.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/unknown.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/xcoff.c +43 -32
- data/crates/backtrace-sys2/src/libbacktrace/xztest.c +2 -2
- data/crates/backtrace-sys2/src/libbacktrace/zstdtest.c +1 -1
- data/crates/backtrace-sys2/src/libbacktrace/ztest.c +1 -1
- data/ext/pf2/Cargo.toml +1 -1
- data/ext/pf2/src/lib.rs +1 -0
- data/ext/pf2/src/profile.rs +7 -3
- data/ext/pf2/src/profile_serializer.rs +6 -13
- data/ext/pf2/src/ringbuffer.rs +1 -3
- data/ext/pf2/src/ruby_init.rs +1 -4
- data/ext/pf2/src/sample.rs +1 -0
- data/ext/pf2/src/serialization/profile.rs +47 -0
- data/ext/pf2/src/serialization/serializer.rs +325 -0
- data/ext/pf2/src/serialization.rs +2 -0
- data/ext/pf2/src/session/configuration.rs +2 -1
- data/ext/pf2/src/session/new_thread_watcher.rs +1 -1
- data/ext/pf2/src/session/ruby_object.rs +1 -5
- data/ext/pf2/src/session.rs +20 -19
- data/ext/pf2/src/signal_scheduler.rs +12 -7
- data/ext/pf2/src/timer_thread_scheduler.rs +11 -3
- data/lib/pf2/cli.rb +3 -1
- data/lib/pf2/reporter/firefox_profiler.rb +397 -0
- data/lib/pf2/reporter/stack_weaver.rb +81 -0
- data/lib/pf2/reporter.rb +3 -392
- data/lib/pf2/serve.rb +3 -1
- data/lib/pf2/session.rb +2 -0
- data/lib/pf2/version.rb +3 -1
- data/lib/pf2.rb +4 -1
- data/rustfmt.toml +1 -0
- metadata +13 -12
- data/crates/backtrace-sys2/src/libbacktrace/libtool.m4 +0 -7436
- data/crates/backtrace-sys2/src/libbacktrace/ltoptions.m4 +0 -369
- data/crates/backtrace-sys2/src/libbacktrace/ltsugar.m4 +0 -123
- data/crates/backtrace-sys2/src/libbacktrace/ltversion.m4 +0 -23
- data/crates/backtrace-sys2/src/libbacktrace/lt~obsolete.m4 +0 -98
data/lib/pf2/reporter.rb
CHANGED
|
@@ -1,393 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
# https://github.com/firefox-devtools/profiler/blob/main/docs-developer/processed-profile-format.md
|
|
6
|
-
class Reporter
|
|
7
|
-
def initialize(profile)
|
|
8
|
-
@profile = Reporter.deep_intize_keys(profile)
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def inspect
|
|
12
|
-
"" # TODO: provide something better
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def emit
|
|
16
|
-
report = {
|
|
17
|
-
meta: {
|
|
18
|
-
interval: 10, # ms; TODO: replace with actual interval
|
|
19
|
-
start_time: 0,
|
|
20
|
-
process_type: 0,
|
|
21
|
-
product: 'ruby',
|
|
22
|
-
stackwalk: 0,
|
|
23
|
-
version: 28,
|
|
24
|
-
preprocessed_profile_version: 47,
|
|
25
|
-
symbolicated: true,
|
|
26
|
-
categories: [
|
|
27
|
-
{
|
|
28
|
-
name: "Logs",
|
|
29
|
-
color: "grey",
|
|
30
|
-
subcategories: ["Unused"],
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
name: "Ruby",
|
|
34
|
-
color: "red",
|
|
35
|
-
subcategories: ["Code"],
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
name: "Native",
|
|
39
|
-
color: "blue",
|
|
40
|
-
subcategories: ["Code"],
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
name: "Native",
|
|
44
|
-
color: "lightblue",
|
|
45
|
-
subcategories: ["Code"],
|
|
46
|
-
},
|
|
47
|
-
],
|
|
48
|
-
marker_schema: [],
|
|
49
|
-
},
|
|
50
|
-
libs: [],
|
|
51
|
-
counters: [],
|
|
52
|
-
threads: @profile[:threads].values.map {|th| ThreadReport.new(th).emit }
|
|
53
|
-
}
|
|
54
|
-
Reporter.deep_camelize_keys(report)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
class ThreadReport
|
|
58
|
-
def initialize(thread)
|
|
59
|
-
@thread = thread
|
|
60
|
-
|
|
61
|
-
# Populated in other methods
|
|
62
|
-
@func_id_map = {}
|
|
63
|
-
@frame_id_map = {}
|
|
64
|
-
@stack_tree_id_map = {}
|
|
65
|
-
|
|
66
|
-
@string_table = {}
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def inspect
|
|
70
|
-
"" # TODO: provide something better
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def emit
|
|
74
|
-
x = weave_native_stack(@thread[:stack_tree])
|
|
75
|
-
@thread[:stack_tree] = x
|
|
76
|
-
func_table = build_func_table
|
|
77
|
-
frame_table = build_frame_table
|
|
78
|
-
stack_table = build_stack_table(func_table, frame_table)
|
|
79
|
-
samples = build_samples
|
|
80
|
-
|
|
81
|
-
string_table = build_string_table
|
|
82
|
-
|
|
83
|
-
{
|
|
84
|
-
process_type: 'default',
|
|
85
|
-
process_name: 'ruby',
|
|
86
|
-
process_startup_time: 0,
|
|
87
|
-
process_shutdown_time: nil,
|
|
88
|
-
register_time: 0,
|
|
89
|
-
unregister_time: nil,
|
|
90
|
-
paused_ranges: [],
|
|
91
|
-
name: "Thread (tid: #{@thread[:thread_id]})",
|
|
92
|
-
is_main_thread: true,
|
|
93
|
-
is_js_tracer: true,
|
|
94
|
-
# FIXME: We can fill the correct PID only after we correctly fill is_main_thread
|
|
95
|
-
# (only one thread could be marked as is_main_thread in a single process)
|
|
96
|
-
pid: @thread[:thread_id],
|
|
97
|
-
tid: @thread[:thread_id],
|
|
98
|
-
samples: samples,
|
|
99
|
-
markers: markers,
|
|
100
|
-
stack_table: stack_table,
|
|
101
|
-
frame_table: frame_table,
|
|
102
|
-
string_array: build_string_table,
|
|
103
|
-
func_table: func_table,
|
|
104
|
-
resource_table: {
|
|
105
|
-
lib: [],
|
|
106
|
-
name: [],
|
|
107
|
-
host: [],
|
|
108
|
-
type: [],
|
|
109
|
-
length: 0,
|
|
110
|
-
},
|
|
111
|
-
native_symbols: [],
|
|
112
|
-
}
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def build_samples
|
|
116
|
-
ret = {
|
|
117
|
-
event_delay: [],
|
|
118
|
-
stack: [],
|
|
119
|
-
time: [],
|
|
120
|
-
duration: [],
|
|
121
|
-
# weight: nil,
|
|
122
|
-
# weight_type: 'samples',
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
@thread[:samples].each do |sample|
|
|
126
|
-
ret[:stack] << @stack_tree_id_map[sample[:stack_tree_id]]
|
|
127
|
-
ret[:time] << sample[:elapsed_ns] / 1000000 # ns -> ms
|
|
128
|
-
ret[:duration] << 1
|
|
129
|
-
ret[:event_delay] << 0
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
ret[:length] = ret[:stack].length
|
|
133
|
-
ret
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
def build_frame_table
|
|
137
|
-
ret = {
|
|
138
|
-
address: [],
|
|
139
|
-
category: [],
|
|
140
|
-
subcategory: [],
|
|
141
|
-
func: [],
|
|
142
|
-
inner_window_id: [],
|
|
143
|
-
implementation: [],
|
|
144
|
-
line: [],
|
|
145
|
-
column: [],
|
|
146
|
-
optimizations: [],
|
|
147
|
-
inline_depth: [],
|
|
148
|
-
native_symbol: [],
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
@thread[:frames].each.with_index do |(id, frame), i|
|
|
152
|
-
ret[:address] << frame[:address].to_s
|
|
153
|
-
ret[:category] << 1
|
|
154
|
-
ret[:subcategory] << 1
|
|
155
|
-
ret[:func] << i # TODO
|
|
156
|
-
ret[:inner_window_id] << nil
|
|
157
|
-
ret[:implementation] << nil
|
|
158
|
-
ret[:line] << frame[:callsite_lineno]
|
|
159
|
-
ret[:column] << nil
|
|
160
|
-
ret[:optimizations] << nil
|
|
161
|
-
ret[:inline_depth] << 0
|
|
162
|
-
ret[:native_symbol] << nil
|
|
163
|
-
|
|
164
|
-
@frame_id_map[id] = i
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
ret[:length] = ret[:address].length
|
|
168
|
-
ret
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
def build_func_table
|
|
172
|
-
ret = {
|
|
173
|
-
name: [],
|
|
174
|
-
is_js: [],
|
|
175
|
-
relevant_for_js: [],
|
|
176
|
-
resource: [],
|
|
177
|
-
file_name: [],
|
|
178
|
-
line_number: [],
|
|
179
|
-
column_number: [],
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
@thread[:frames].each.with_index do |(id, frame), i|
|
|
183
|
-
native = (frame[:entry_type] == 'Native')
|
|
184
|
-
label = "#{native ? "Native: " : ""}#{frame[:full_label]}"
|
|
185
|
-
ret[:name] << string_id(label)
|
|
186
|
-
ret[:is_js] << !native
|
|
187
|
-
ret[:relevant_for_js] << false
|
|
188
|
-
ret[:resource] << -1
|
|
189
|
-
ret[:file_name] << string_id(frame[:file_name])
|
|
190
|
-
ret[:line_number] << frame[:function_first_lineno]
|
|
191
|
-
ret[:column_number] << nil
|
|
192
|
-
|
|
193
|
-
@func_id_map[id] = i
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
ret[:length] = ret[:name].length
|
|
197
|
-
ret
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
# "Weave" the native stack into the Ruby stack.
|
|
201
|
-
#
|
|
202
|
-
# Strategy:
|
|
203
|
-
# - Split the stack into Ruby and Native parts
|
|
204
|
-
# - Start from the root of the Native stack
|
|
205
|
-
# - Dig in to the native stack until we hit a rb_vm_exec(), which marks a call into Ruby code
|
|
206
|
-
# - Switch to Ruby stack. Keep digging until we hit a Cfunc call, then switch back to Native stack
|
|
207
|
-
# - Repeat until we consume the entire stack
|
|
208
|
-
def weave_native_stack(stack_tree)
|
|
209
|
-
collected_paths = []
|
|
210
|
-
tree_to_array_of_paths(stack_tree, @thread[:frames], [], collected_paths)
|
|
211
|
-
collected_paths = collected_paths.map do |path|
|
|
212
|
-
next if path.size == 0
|
|
213
|
-
|
|
214
|
-
new_path = []
|
|
215
|
-
new_path << path.shift # root
|
|
216
|
-
|
|
217
|
-
# Split the stack into Ruby and Native parts
|
|
218
|
-
native_path, ruby_path = path.partition do |frame|
|
|
219
|
-
frame_id = frame[:frame_id]
|
|
220
|
-
@thread[:frames][frame_id][:entry_type] == 'Native'
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
mode = :native
|
|
224
|
-
|
|
225
|
-
loop do
|
|
226
|
-
break if ruby_path.size == 0 && native_path.size == 0
|
|
227
|
-
|
|
228
|
-
case mode
|
|
229
|
-
when :ruby
|
|
230
|
-
if ruby_path.size == 0
|
|
231
|
-
mode = :native
|
|
232
|
-
next
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
next_node = ruby_path[0]
|
|
236
|
-
new_path << ruby_path.shift
|
|
237
|
-
next_node_frame = @thread[:frames][next_node[:frame_id]]
|
|
238
|
-
if native_path.size > 0
|
|
239
|
-
# Search the remainder of the native stack for the same address
|
|
240
|
-
# Note: This isn't a very efficient way for the job... but it still works
|
|
241
|
-
ruby_addr = next_node_frame[:address]
|
|
242
|
-
native_path[0..].each do |native_node|
|
|
243
|
-
native_addr = @thread[:frames][native_node[:frame_id]][:address]
|
|
244
|
-
if ruby_addr && native_addr && ruby_addr == native_addr
|
|
245
|
-
# A match has been found. Switch to native mode
|
|
246
|
-
mode = :native
|
|
247
|
-
break
|
|
248
|
-
end
|
|
249
|
-
end
|
|
250
|
-
end
|
|
251
|
-
when :native
|
|
252
|
-
if native_path.size == 0
|
|
253
|
-
mode = :ruby
|
|
254
|
-
next
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
# Dig until we meet a rb_vm_exec
|
|
258
|
-
next_node = native_path[0]
|
|
259
|
-
new_path << native_path.shift
|
|
260
|
-
if @thread[:frames][next_node[:frame_id]][:full_label] =~ /vm_exec_core/ # VM_EXEC in vm_exec.h
|
|
261
|
-
mode = :ruby
|
|
262
|
-
end
|
|
263
|
-
end
|
|
264
|
-
end
|
|
265
|
-
|
|
266
|
-
new_path
|
|
267
|
-
end
|
|
268
|
-
|
|
269
|
-
# reconstruct stack_tree
|
|
270
|
-
new_stack_tree = array_of_paths_to_tree(collected_paths)
|
|
271
|
-
new_stack_tree
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
def tree_to_array_of_paths(stack_tree, frames, path, collected_paths)
|
|
275
|
-
new_path = path + [{ frame_id: stack_tree[:frame_id], node_id: stack_tree[:node_id] }]
|
|
276
|
-
if stack_tree[:children].empty?
|
|
277
|
-
collected_paths << new_path
|
|
278
|
-
else
|
|
279
|
-
stack_tree[:children].each do |frame_id, child|
|
|
280
|
-
tree_to_array_of_paths(child, frames, new_path, collected_paths)
|
|
281
|
-
end
|
|
282
|
-
end
|
|
283
|
-
end
|
|
284
|
-
|
|
285
|
-
def array_of_paths_to_tree(paths)
|
|
286
|
-
new_stack_tree = { children: {}, node_id: 0, frame_id: 0 }
|
|
287
|
-
paths.each do |path|
|
|
288
|
-
current = new_stack_tree
|
|
289
|
-
path[1..].each do |frame|
|
|
290
|
-
frame_id = frame[:frame_id]
|
|
291
|
-
node_id = frame[:node_id]
|
|
292
|
-
current[:children][frame_id] ||= { children: {}, node_id: node_id, frame_id: frame_id }
|
|
293
|
-
current = current[:children][frame_id]
|
|
294
|
-
end
|
|
295
|
-
end
|
|
296
|
-
new_stack_tree
|
|
297
|
-
end
|
|
298
|
-
|
|
299
|
-
def build_stack_table(func_table, frame_table)
|
|
300
|
-
ret = {
|
|
301
|
-
frame: [],
|
|
302
|
-
category: [],
|
|
303
|
-
subcategory: [],
|
|
304
|
-
prefix: [],
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
queue = []
|
|
308
|
-
|
|
309
|
-
@thread[:stack_tree][:children].each {|_, c| queue << [nil, c] }
|
|
310
|
-
|
|
311
|
-
loop do
|
|
312
|
-
break if queue.size == 0
|
|
313
|
-
|
|
314
|
-
prefix, node = queue.shift
|
|
315
|
-
ret[:frame] << @frame_id_map[node[:frame_id]]
|
|
316
|
-
ret[:category] << (build_string_table[func_table[:name][frame_table[:func][@frame_id_map[node[:frame_id]]]]].start_with?('Native:') ? 2 : 1)
|
|
317
|
-
ret[:subcategory] << nil
|
|
318
|
-
ret[:prefix] << prefix
|
|
319
|
-
|
|
320
|
-
# The index of this frame - children can refer to this frame using this index as prefix
|
|
321
|
-
frame_index = ret[:frame].length - 1
|
|
322
|
-
@stack_tree_id_map[node[:node_id]] = frame_index
|
|
323
|
-
|
|
324
|
-
# Enqueue children nodes
|
|
325
|
-
node[:children].each {|_, c| queue << [frame_index, c] }
|
|
326
|
-
end
|
|
327
|
-
|
|
328
|
-
ret[:length] = ret[:frame].length
|
|
329
|
-
ret
|
|
330
|
-
end
|
|
331
|
-
|
|
332
|
-
def build_string_table
|
|
333
|
-
@string_table.sort_by {|_, v| v}.map {|s| s[0] }
|
|
334
|
-
end
|
|
335
|
-
|
|
336
|
-
def string_id(str)
|
|
337
|
-
return @string_table[str] if @string_table.has_key?(str)
|
|
338
|
-
@string_table[str] = @string_table.length
|
|
339
|
-
@string_table[str]
|
|
340
|
-
end
|
|
341
|
-
|
|
342
|
-
def markers
|
|
343
|
-
{
|
|
344
|
-
data: [],
|
|
345
|
-
name: [],
|
|
346
|
-
time: [],
|
|
347
|
-
start_time: [],
|
|
348
|
-
end_time: [],
|
|
349
|
-
phase: [],
|
|
350
|
-
category: [],
|
|
351
|
-
length: 0
|
|
352
|
-
}
|
|
353
|
-
end
|
|
354
|
-
end
|
|
355
|
-
|
|
356
|
-
# Util functions
|
|
357
|
-
class << self
|
|
358
|
-
def snake_to_camel(s)
|
|
359
|
-
return "isJS" if s == "is_js"
|
|
360
|
-
return "relevantForJS" if s == "relevant_for_js"
|
|
361
|
-
return "innerWindowID" if s == "inner_window_id"
|
|
362
|
-
s.split('_').inject([]) {|buffer, p| buffer.push(buffer.size == 0 ? p : p.capitalize) }.join
|
|
363
|
-
end
|
|
364
|
-
|
|
365
|
-
def deep_transform_keys(value, &block)
|
|
366
|
-
case value
|
|
367
|
-
when Array
|
|
368
|
-
value.map {|v| deep_transform_keys(v, &block) }
|
|
369
|
-
when Hash
|
|
370
|
-
Hash[value.map {|k, v| [yield(k), deep_transform_keys(v, &block)] }]
|
|
371
|
-
else
|
|
372
|
-
value
|
|
373
|
-
end
|
|
374
|
-
end
|
|
375
|
-
|
|
376
|
-
def deep_camelize_keys(value)
|
|
377
|
-
deep_transform_keys(value) do |key|
|
|
378
|
-
snake_to_camel(key.to_s).to_sym
|
|
379
|
-
end
|
|
380
|
-
end
|
|
381
|
-
|
|
382
|
-
def deep_intize_keys(value)
|
|
383
|
-
deep_transform_keys(value) do |key|
|
|
384
|
-
if key.to_s.to_i.to_s == key.to_s
|
|
385
|
-
key.to_s.to_i
|
|
386
|
-
else
|
|
387
|
-
key
|
|
388
|
-
end
|
|
389
|
-
end
|
|
390
|
-
end
|
|
391
|
-
end
|
|
392
|
-
end
|
|
393
|
-
end
|
|
3
|
+
require_relative './reporter/stack_weaver'
|
|
4
|
+
require_relative './reporter/firefox_profiler'
|
data/lib/pf2/serve.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'json'
|
|
2
4
|
require 'logger'
|
|
3
5
|
require 'uri'
|
|
@@ -28,7 +30,7 @@ module Pf2
|
|
|
28
30
|
profile = JSON.parse(profile, symbolize_names: true, max_nesting: false)
|
|
29
31
|
res.header['Content-Type'] = 'application/json'
|
|
30
32
|
res.header['Access-Control-Allow-Origin'] = '*'
|
|
31
|
-
res.body = JSON.generate(Pf2::Reporter.new((profile)).emit)
|
|
33
|
+
res.body = JSON.generate(Pf2::Reporter::FirefoxProfiler.new((profile)).emit)
|
|
32
34
|
Pf2.start
|
|
33
35
|
end
|
|
34
36
|
|
data/lib/pf2/session.rb
CHANGED
data/lib/pf2/version.rb
CHANGED
data/lib/pf2.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative 'pf2/pf2'
|
|
2
4
|
require_relative 'pf2/session'
|
|
3
5
|
require_relative 'pf2/version'
|
|
@@ -18,7 +20,8 @@ module Pf2
|
|
|
18
20
|
raise ArgumentError, "block required" unless block_given?
|
|
19
21
|
start(threads: Thread.list)
|
|
20
22
|
yield
|
|
21
|
-
stop
|
|
23
|
+
result = stop
|
|
22
24
|
@@session = nil # let GC clean up the session
|
|
25
|
+
result
|
|
23
26
|
end
|
|
24
27
|
end
|
data/rustfmt.toml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
use_small_heuristics = "Max"
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pf2
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daisuke Aritomo
|
|
8
8
|
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 2025-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: rake-compiler
|
|
@@ -27,16 +27,16 @@ dependencies:
|
|
|
27
27
|
name: rb_sys
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
|
-
- -
|
|
30
|
+
- - '='
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: 0.9.
|
|
32
|
+
version: 0.9.105
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
|
-
- -
|
|
37
|
+
- - '='
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: 0.9.
|
|
39
|
+
version: 0.9.105
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
41
|
name: webrick
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -126,12 +126,7 @@ files:
|
|
|
126
126
|
- crates/backtrace-sys2/src/libbacktrace/install-sh
|
|
127
127
|
- crates/backtrace-sys2/src/libbacktrace/instrumented_alloc.c
|
|
128
128
|
- crates/backtrace-sys2/src/libbacktrace/internal.h
|
|
129
|
-
- crates/backtrace-sys2/src/libbacktrace/libtool.m4
|
|
130
129
|
- crates/backtrace-sys2/src/libbacktrace/ltmain.sh
|
|
131
|
-
- crates/backtrace-sys2/src/libbacktrace/ltoptions.m4
|
|
132
|
-
- crates/backtrace-sys2/src/libbacktrace/ltsugar.m4
|
|
133
|
-
- crates/backtrace-sys2/src/libbacktrace/ltversion.m4
|
|
134
|
-
- crates/backtrace-sys2/src/libbacktrace/lt~obsolete.m4
|
|
135
130
|
- crates/backtrace-sys2/src/libbacktrace/macho.c
|
|
136
131
|
- crates/backtrace-sys2/src/libbacktrace/missing
|
|
137
132
|
- crates/backtrace-sys2/src/libbacktrace/mmap.c
|
|
@@ -171,6 +166,9 @@ files:
|
|
|
171
166
|
- ext/pf2/src/ruby_internal_apis.rs
|
|
172
167
|
- ext/pf2/src/sample.rs
|
|
173
168
|
- ext/pf2/src/scheduler.rs
|
|
169
|
+
- ext/pf2/src/serialization.rs
|
|
170
|
+
- ext/pf2/src/serialization/profile.rs
|
|
171
|
+
- ext/pf2/src/serialization/serializer.rs
|
|
174
172
|
- ext/pf2/src/session.rs
|
|
175
173
|
- ext/pf2/src/session/configuration.rs
|
|
176
174
|
- ext/pf2/src/session/new_thread_watcher.rs
|
|
@@ -183,9 +181,12 @@ files:
|
|
|
183
181
|
- lib/pf2.rb
|
|
184
182
|
- lib/pf2/cli.rb
|
|
185
183
|
- lib/pf2/reporter.rb
|
|
184
|
+
- lib/pf2/reporter/firefox_profiler.rb
|
|
185
|
+
- lib/pf2/reporter/stack_weaver.rb
|
|
186
186
|
- lib/pf2/serve.rb
|
|
187
187
|
- lib/pf2/session.rb
|
|
188
188
|
- lib/pf2/version.rb
|
|
189
|
+
- rustfmt.toml
|
|
189
190
|
homepage: https://github.com/osyoyu/pf2
|
|
190
191
|
licenses:
|
|
191
192
|
- MIT
|
|
@@ -208,7 +209,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
208
209
|
- !ruby/object:Gem::Version
|
|
209
210
|
version: '0'
|
|
210
211
|
requirements: []
|
|
211
|
-
rubygems_version: 3.6.
|
|
212
|
+
rubygems_version: 3.6.2
|
|
212
213
|
specification_version: 4
|
|
213
214
|
summary: Yet another Ruby profiler
|
|
214
215
|
test_files: []
|