stackprof 0.2.16 → 0.2.17
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/.github/workflows/ci.yml +43 -0
- data/README.md +54 -55
- data/Rakefile +11 -25
- data/ext/stackprof/stackprof.c +20 -8
- data/lib/stackprof.rb +1 -1
- data/lib/stackprof/report.rb +1 -1
- data/stackprof.gemspec +1 -1
- data/test/test_stackprof.rb +36 -9
- metadata +7 -8
- data/.travis.yml +0 -21
- data/Dockerfile +0 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b55691b8d1966ba4b2b2458a4908b2a2d5b65f2074dfe3b3b1b6350f752704ec
|
4
|
+
data.tar.gz: 79e2a0508a1c722f39cc61d39b0577cfb5520669a7a2db4cadac6c49dcb1267a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2fa22779f03c332a3680f526bf1df29553588773fabeb00da327af3525018e535e973bafd990254c6ad50516faf5e8b1d087bb7c208c99d0b512d99ccdef53bb
|
7
|
+
data.tar.gz: 73ba1328c793b0c0c4657e7826f4bf2cd52102c61a2ca2e3e0b1c5240ffe96ee0ec328ea831b1592c10b4e13c6aec2bb9d28fd05e93ddef999d5131e55124362
|
@@ -0,0 +1,43 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
rubies:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
strategy:
|
9
|
+
fail-fast: false
|
10
|
+
matrix:
|
11
|
+
ruby: [ ruby-head, '3.0', '2.7', '2.6', '2.5', '2.4', '2.3', '2.2' ]
|
12
|
+
steps:
|
13
|
+
- name: Checkout
|
14
|
+
uses: actions/checkout@v2
|
15
|
+
- name: Set up Ruby
|
16
|
+
uses: ruby/setup-ruby@v1
|
17
|
+
with:
|
18
|
+
ruby-version: ${{ matrix.ruby }}
|
19
|
+
- name: Install dependencies
|
20
|
+
run: bundle install
|
21
|
+
- name: Run test
|
22
|
+
run: rake
|
23
|
+
- name: Install gem
|
24
|
+
run: rake install
|
25
|
+
platforms:
|
26
|
+
strategy:
|
27
|
+
matrix:
|
28
|
+
os: [macos]
|
29
|
+
ruby: ['3.0']
|
30
|
+
runs-on: ${{ matrix.os }}-latest
|
31
|
+
steps:
|
32
|
+
- name: Checkout
|
33
|
+
uses: actions/checkout@v2
|
34
|
+
- name: Set up Ruby
|
35
|
+
uses: ruby/setup-ruby@v1
|
36
|
+
with:
|
37
|
+
ruby-version: ${{ matrix.ruby }}
|
38
|
+
- name: Install dependencies
|
39
|
+
run: bundle install
|
40
|
+
- name: Run test
|
41
|
+
run: rake
|
42
|
+
- name: Install gem
|
43
|
+
run: rake install
|
data/README.md
CHANGED
@@ -81,21 +81,21 @@ $ stackprof tmp/stackprof-cpu-*.dump --method 'Object#present?'
|
|
81
81
|
|
82
82
|
For an experimental version of WebUI reporting of stackprof, see [stackprof-webnav](https://github.com/alisnic/stackprof-webnav)
|
83
83
|
|
84
|
-
|
84
|
+
To generate flamegraphs with Stackprof, additional data must be collected using the `raw: true` flag. Once you've collected results with this flag enabled, generate a flamegraph with:
|
85
85
|
|
86
86
|
```
|
87
87
|
$ stackprof --flamegraph tmp/stackprof-cpu-myapp.dump > tmp/flamegraph
|
88
88
|
```
|
89
89
|
|
90
|
-
|
90
|
+
After the flamegraph has been generated, you can generate a viewer command with:
|
91
91
|
|
92
92
|
```
|
93
93
|
$ stackprof --flamegraph-viewer=tmp/flamegraph
|
94
94
|
```
|
95
95
|
|
96
|
-
The `--flamegraph-viewer` command will output the exact shell command you need to run to open the `tmp/flamegraph` you generated with the built
|
96
|
+
The `--flamegraph-viewer` command will output the exact shell command you need to run in order to open the `tmp/flamegraph` you generated with the built-in stackprof flamegraph viewer:
|
97
97
|
|
98
|
-

|
98
|
+

|
99
99
|
|
100
100
|
Alternatively, you can generate a flamegraph that uses [d3-flame-graph](https://github.com/spiermar/d3-flame-graph):
|
101
101
|
|
@@ -107,16 +107,16 @@ And just open the result by your browser.
|
|
107
107
|
|
108
108
|
## Sampling
|
109
109
|
|
110
|
-
|
110
|
+
Four sampling modes are supported:
|
111
111
|
|
112
|
-
-
|
113
|
-
-
|
114
|
-
-
|
115
|
-
-
|
112
|
+
- `:wall` (using `ITIMER_REAL` and `SIGALRM`) [default mode]
|
113
|
+
- `:cpu` (using `ITIMER_PROF` and `SIGPROF`)
|
114
|
+
- `:object` (using `RUBY_INTERNAL_EVENT_NEWOBJ`)
|
115
|
+
- `:custom` (user-defined via `StackProf.sample`)
|
116
116
|
|
117
|
-
|
117
|
+
Samplers have a tuneable interval which can be used to reduce overhead or increase granularity:
|
118
118
|
|
119
|
-
-
|
119
|
+
- Wall time: sample every _interval_ microseconds of wallclock time (default: 1000)
|
120
120
|
|
121
121
|
```ruby
|
122
122
|
StackProf.run(mode: :wall, out: 'tmp/stackprof.dump', interval: 1000) do
|
@@ -124,7 +124,7 @@ StackProf.run(mode: :wall, out: 'tmp/stackprof.dump', interval: 1000) do
|
|
124
124
|
end
|
125
125
|
```
|
126
126
|
|
127
|
-
-
|
127
|
+
- CPU time: sample every _interval_ microseconds of CPU activity (default: 1000 = 1 millisecond)
|
128
128
|
|
129
129
|
```ruby
|
130
130
|
StackProf.run(mode: :cpu, out: 'tmp/stackprof.dump', interval: 1000) do
|
@@ -132,7 +132,7 @@ StackProf.run(mode: :cpu, out: 'tmp/stackprof.dump', interval: 1000) do
|
|
132
132
|
end
|
133
133
|
```
|
134
134
|
|
135
|
-
-
|
135
|
+
- Object allocation: sample every _interval_ allocations (default: 1)
|
136
136
|
|
137
137
|
|
138
138
|
```ruby
|
@@ -141,36 +141,36 @@ StackProf.run(mode: :object, out: 'tmp/stackprof.dump', interval: 1) do
|
|
141
141
|
end
|
142
142
|
```
|
143
143
|
|
144
|
-
|
145
|
-
including both mark and sweep phases.
|
146
|
-
that are hard to follow
|
147
|
-
|
144
|
+
By default, samples taken during garbage collection will show as garbage collection frames
|
145
|
+
including both mark and sweep phases. For longer traces, these can leave gaps in a flamegraph
|
146
|
+
that are hard to follow. They can be disabled by setting the `ignore_gc` option to true.
|
147
|
+
Garbage collection time will still be present in the profile but not explicitly marked with
|
148
148
|
its own frame.
|
149
149
|
|
150
|
-
|
150
|
+
Samples are taken using a combination of three new C-APIs in ruby 2.1:
|
151
151
|
|
152
|
-
-
|
152
|
+
- Signal handlers enqueue a sampling job using `rb_postponed_job_register_one`.
|
153
153
|
this ensures callstack samples can be taken safely, in case the VM is garbage collecting
|
154
154
|
or in some other inconsistent state during the interruption.
|
155
155
|
|
156
|
-
-
|
157
|
-
to the VM's call stack.
|
156
|
+
- Stack frames are collected via `rb_profile_frames`, which provides low-overhead C-API access
|
157
|
+
to the VM's call stack. No object allocations occur in this path, allowing stackprof to collect
|
158
158
|
callstacks in allocation mode.
|
159
159
|
|
160
|
-
-
|
160
|
+
- In allocation mode, samples are taken via `rb_tracepoint_new(RUBY_INTERNAL_EVENT_NEWOBJ)`,
|
161
161
|
which provides a notification every time the VM allocates a new object.
|
162
162
|
|
163
163
|
## Aggregation
|
164
164
|
|
165
|
-
|
166
|
-
|
165
|
+
Each sample consists of N stack frames, where a frame looks something like `MyClass#method` or `block in MySingleton.method`.
|
166
|
+
For each of these frames in the sample, the profiler collects a few pieces of metadata:
|
167
167
|
|
168
|
-
- samples
|
169
|
-
- total_samples
|
170
|
-
- lines
|
171
|
-
- edges
|
168
|
+
- `samples`: Number of samples where this was the topmost frame
|
169
|
+
- `total_samples`: Samples where this frame was in the stack
|
170
|
+
- `lines`: Samples per line number in this frame
|
171
|
+
- `edges`: Samples per callee frame (methods invoked by this frame)
|
172
172
|
|
173
|
-
|
173
|
+
The aggregation algorithm is roughly equivalent to the following pseudo code:
|
174
174
|
|
175
175
|
``` ruby
|
176
176
|
trap('PROF') do
|
@@ -189,16 +189,16 @@ trap('PROF') do
|
|
189
189
|
end
|
190
190
|
```
|
191
191
|
|
192
|
-
|
192
|
+
This technique builds up an incremental call graph from the samples. On any given frame,
|
193
193
|
the sum of the outbound edge weights is equal to total samples collected on that frame
|
194
194
|
(`frame.total_samples == frame.edges.values.sum`).
|
195
195
|
|
196
196
|
## Reporting
|
197
197
|
|
198
|
-
|
199
|
-
-
|
200
|
-
-
|
201
|
-
-
|
198
|
+
Multiple reporting modes are supported:
|
199
|
+
- Text
|
200
|
+
- Dotgraph
|
201
|
+
- Source annotation
|
202
202
|
|
203
203
|
### `StackProf::Report.new(data).print_text`
|
204
204
|
|
@@ -217,8 +217,6 @@ multiple reporting modes are supported:
|
|
217
217
|
|
218
218
|
### `StackProf::Report.new(data).print_graphviz`
|
219
219
|
|
220
|
-

|
221
|
-
|
222
220
|
```
|
223
221
|
digraph profile {
|
224
222
|
70346498324780 [size=23.5531914893617] [fontsize=23.5531914893617] [shape=box] [label="A#pow\n91 (48.4%)\r"];
|
@@ -265,8 +263,8 @@ block in A#math (/Users/tmm1/code/stackprof/sample.rb:21)
|
|
265
263
|
|
266
264
|
## Usage
|
267
265
|
|
268
|
-
|
269
|
-
|
266
|
+
The profiler is compiled as a C-extension and exposes a simple api: `StackProf.run(mode: [:cpu|:wall|:object])`.
|
267
|
+
The `run` method takes a block of code and returns a profile as a simple hash.
|
270
268
|
|
271
269
|
``` ruby
|
272
270
|
# sample after every 1ms of cpu activity
|
@@ -275,12 +273,12 @@ profile = StackProf.run(mode: :cpu, interval: 1000) do
|
|
275
273
|
end
|
276
274
|
```
|
277
275
|
|
278
|
-
|
279
|
-
(as json/marshal for example) for later processing.
|
276
|
+
This profile data structure is part of the public API, and is intended to be saved
|
277
|
+
(as json/marshal for example) for later processing. The reports above can be generated
|
280
278
|
by passing this structure into `StackProf::Report.new`.
|
281
279
|
|
282
|
-
|
283
|
-
identifying information such as its name, file and line.
|
280
|
+
The format itself is very simple. It contains a header and a list of frames. Each frame has a unique ID and
|
281
|
+
identifying information such as its name, file, and line. The frame also contains sampling data, including per-line
|
284
282
|
samples, and a list of relationships to other frames represented as weighted edges.
|
285
283
|
|
286
284
|
``` ruby
|
@@ -307,20 +305,21 @@ samples, and a list of relationships to other frames represented as weighted edg
|
|
307
305
|
:lines=>{8=>1}},
|
308
306
|
```
|
309
307
|
|
310
|
-
|
308
|
+
Above, `A#pow` was involved in 91 samples, and in all cases it was at the top of the stack on line 12.
|
311
309
|
|
312
|
-
`A#initialize` was in 185 samples, but it was at the top of the stack in only 1 sample.
|
313
|
-
divided up between its callee edges.
|
310
|
+
`A#initialize` was in 185 samples, but it was at the top of the stack in only 1 sample. The rest of the samples are
|
311
|
+
divided up between its callee edges. All 91 calls to `A#pow` came from `A#initialize`, as seen by the edge numbered
|
314
312
|
`70346498324780`.
|
315
313
|
|
316
314
|
## Advanced usage
|
317
315
|
|
318
|
-
|
319
|
-
multiple start
|
316
|
+
The profiler can be started and stopped manually. Results are accumulated until retrieval, across
|
317
|
+
multiple `start`/`stop` invocations.
|
320
318
|
|
321
319
|
``` ruby
|
322
|
-
StackProf.running?
|
320
|
+
StackProf.running? # => false
|
323
321
|
StackProf.start(mode: :cpu)
|
322
|
+
StackProf.running? # => true
|
324
323
|
StackProf.stop
|
325
324
|
StackProf.results('/tmp/some.file')
|
326
325
|
```
|
@@ -331,14 +330,14 @@ StackProf.results('/tmp/some.file')
|
|
331
330
|
|
332
331
|
Option | Meaning
|
333
332
|
------- | ---------
|
334
|
-
`mode` |
|
335
|
-
`out` |
|
336
|
-
`interval` |
|
333
|
+
`mode` | Mode of sampling: `:cpu`, `:wall`, `:object`, or `:custom` [c.f.](#sampling)
|
334
|
+
`out` | The target file, which will be overwritten
|
335
|
+
`interval` | Mode-relative sample rate [c.f.](#sampling)
|
337
336
|
`ignore_gc` | Ignore garbage collection frames
|
338
|
-
`aggregate` |
|
339
|
-
`raw` |
|
340
|
-
`metadata` |
|
341
|
-
`save_every`| (
|
337
|
+
`aggregate` | Defaults: `true` - if `false` disables [aggregation](#aggregation)
|
338
|
+
`raw` | Defaults `false` - if `true` collects the extra data required by the `--flamegraph` and `--stackcollapse` report types
|
339
|
+
`metadata` | Defaults to `{}`. Must be a `Hash`. metadata associated with this profile
|
340
|
+
`save_every`| (Rack middleware only) write the target file after this many requests
|
342
341
|
|
343
342
|
## Todo
|
344
343
|
|
data/Rakefile
CHANGED
@@ -1,31 +1,17 @@
|
|
1
|
-
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
GEMSPEC = Gem::Specification::load('stackprof.gemspec')
|
8
|
-
|
9
|
-
require 'rubygems/package_task'
|
10
|
-
Gem::PackageTask.new(GEMSPEC) do |pkg|
|
4
|
+
Rake::TestTask.new(:test) do |t|
|
5
|
+
t.libs << "test"
|
6
|
+
t.libs << "lib"
|
7
|
+
t.test_files = FileList["test/**/test_*.rb"]
|
11
8
|
end
|
12
9
|
|
13
|
-
|
14
|
-
# Ruby Extension
|
15
|
-
# ==========================================================
|
10
|
+
require "rake/extensiontask"
|
16
11
|
|
17
|
-
|
18
|
-
|
19
|
-
ext.lib_dir =
|
12
|
+
Rake::ExtensionTask.new("stackprof") do |ext|
|
13
|
+
ext.ext_dir = "ext/stackprof"
|
14
|
+
ext.lib_dir = "lib/stackprof"
|
20
15
|
end
|
21
|
-
task :build => :compile
|
22
16
|
|
23
|
-
|
24
|
-
# Testing
|
25
|
-
# ==========================================================
|
26
|
-
|
27
|
-
require 'rake/testtask'
|
28
|
-
Rake::TestTask.new 'test' do |t|
|
29
|
-
t.test_files = FileList['test/test_*.rb']
|
30
|
-
end
|
31
|
-
task :test => :build
|
17
|
+
task default: %i(compile test)
|
data/ext/stackprof/stackprof.c
CHANGED
@@ -22,6 +22,14 @@
|
|
22
22
|
#define FAKE_FRAME_MARK INT2FIX(1)
|
23
23
|
#define FAKE_FRAME_SWEEP INT2FIX(2)
|
24
24
|
|
25
|
+
/*
|
26
|
+
* As of Ruby 3.0, it should be safe to read stack frames at any time
|
27
|
+
* See https://github.com/ruby/ruby/commit/0e276dc458f94d9d79a0f7c7669bde84abe80f21
|
28
|
+
*/
|
29
|
+
#if RUBY_API_VERSION_MAJOR < 3
|
30
|
+
#define USE_POSTPONED_JOB
|
31
|
+
#endif
|
32
|
+
|
25
33
|
static const char *fake_frame_cstrs[] = {
|
26
34
|
"(garbage collection)",
|
27
35
|
"(marking)",
|
@@ -596,31 +604,30 @@ stackprof_record_gc_samples()
|
|
596
604
|
static void
|
597
605
|
stackprof_gc_job_handler(void *data)
|
598
606
|
{
|
599
|
-
static int in_signal_handler = 0;
|
600
|
-
if (in_signal_handler) return;
|
601
607
|
if (!_stackprof.running) return;
|
602
608
|
|
603
|
-
in_signal_handler++;
|
604
609
|
stackprof_record_gc_samples();
|
605
|
-
in_signal_handler--;
|
606
610
|
}
|
607
611
|
|
608
612
|
static void
|
609
613
|
stackprof_job_handler(void *data)
|
610
614
|
{
|
611
|
-
static int in_signal_handler = 0;
|
612
|
-
if (in_signal_handler) return;
|
613
615
|
if (!_stackprof.running) return;
|
614
616
|
|
615
|
-
in_signal_handler++;
|
616
617
|
stackprof_record_sample();
|
617
|
-
in_signal_handler--;
|
618
618
|
}
|
619
619
|
|
620
620
|
static void
|
621
621
|
stackprof_signal_handler(int sig, siginfo_t *sinfo, void *ucontext)
|
622
622
|
{
|
623
|
+
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
|
624
|
+
|
623
625
|
_stackprof.overall_signals++;
|
626
|
+
|
627
|
+
if (!_stackprof.running) return;
|
628
|
+
if (!ruby_native_thread_p()) return;
|
629
|
+
if (pthread_mutex_trylock(&lock)) return;
|
630
|
+
|
624
631
|
if (!_stackprof.ignore_gc && rb_during_gc()) {
|
625
632
|
VALUE mode = rb_gc_latest_gc_info(sym_state);
|
626
633
|
if (mode == sym_marking) {
|
@@ -631,8 +638,13 @@ stackprof_signal_handler(int sig, siginfo_t *sinfo, void *ucontext)
|
|
631
638
|
_stackprof.unrecorded_gc_samples++;
|
632
639
|
rb_postponed_job_register_one(0, stackprof_gc_job_handler, (void*)0);
|
633
640
|
} else {
|
641
|
+
#ifdef USE_POSTPONED_JOB
|
634
642
|
rb_postponed_job_register_one(0, stackprof_job_handler, (void*)0);
|
643
|
+
#else
|
644
|
+
stackprof_job_handler(0);
|
645
|
+
#endif
|
635
646
|
}
|
647
|
+
pthread_mutex_unlock(&lock);
|
636
648
|
}
|
637
649
|
|
638
650
|
static void
|
data/lib/stackprof.rb
CHANGED
data/lib/stackprof/report.rb
CHANGED
@@ -445,7 +445,7 @@ module StackProf
|
|
445
445
|
call, total = info.values_at(:samples, :total_samples)
|
446
446
|
break if total < node_minimum || (limit && index >= limit)
|
447
447
|
|
448
|
-
sample = ''
|
448
|
+
sample = ''.dup
|
449
449
|
sample << "#{call} (%2.1f%%)\\rof " % (call*100.0/overall_samples) if call < total
|
450
450
|
sample << "#{total} (%2.1f%%)\\r" % (total*100.0/overall_samples)
|
451
451
|
fontsize = (1.0 * call / max_samples) * 28 + 10
|
data/stackprof.gemspec
CHANGED
data/test/test_stackprof.rb
CHANGED
@@ -39,16 +39,30 @@ class StackProfTest < MiniTest::Test
|
|
39
39
|
end
|
40
40
|
assert_equal :object, profile[:mode]
|
41
41
|
assert_equal 1, profile[:interval]
|
42
|
-
|
42
|
+
if RUBY_VERSION >= '3'
|
43
|
+
assert_equal 4, profile[:samples]
|
44
|
+
else
|
45
|
+
assert_equal 2, profile[:samples]
|
46
|
+
end
|
43
47
|
|
44
48
|
frame = profile[:frames].values.first
|
45
49
|
assert_includes frame[:name], "StackProfTest#test_object_allocation"
|
46
50
|
assert_equal 2, frame[:samples]
|
47
51
|
assert_includes [profile_base_line - 2, profile_base_line], frame[:line]
|
48
|
-
|
49
|
-
|
52
|
+
if RUBY_VERSION >= '3'
|
53
|
+
assert_equal [2, 1], frame[:lines][profile_base_line+1]
|
54
|
+
assert_equal [2, 1], frame[:lines][profile_base_line+2]
|
55
|
+
else
|
56
|
+
assert_equal [1, 1], frame[:lines][profile_base_line+1]
|
57
|
+
assert_equal [1, 1], frame[:lines][profile_base_line+2]
|
58
|
+
end
|
50
59
|
frame = profile[:frames].values[1] if RUBY_VERSION < '2.3'
|
51
|
-
|
60
|
+
|
61
|
+
if RUBY_VERSION >= '3'
|
62
|
+
assert_equal [4, 0], frame[:lines][profile_base_line]
|
63
|
+
else
|
64
|
+
assert_equal [2, 0], frame[:lines][profile_base_line]
|
65
|
+
end
|
52
66
|
end
|
53
67
|
|
54
68
|
def test_object_allocation_interval
|
@@ -64,7 +78,8 @@ class StackProfTest < MiniTest::Test
|
|
64
78
|
end
|
65
79
|
|
66
80
|
assert_operator profile[:samples], :>=, 1
|
67
|
-
|
81
|
+
offset = RUBY_VERSION >= '3' ? 1 : 0
|
82
|
+
frame = profile[:frames].values[offset]
|
68
83
|
assert_includes frame[:name], "StackProfTest#math"
|
69
84
|
end
|
70
85
|
|
@@ -74,7 +89,11 @@ class StackProfTest < MiniTest::Test
|
|
74
89
|
end
|
75
90
|
|
76
91
|
frame = profile[:frames].values.first
|
77
|
-
|
92
|
+
if RUBY_VERSION >= '3'
|
93
|
+
assert_equal "IO.select", frame[:name]
|
94
|
+
else
|
95
|
+
assert_equal "StackProfTest#idle", frame[:name]
|
96
|
+
end
|
78
97
|
assert_in_delta 200, frame[:samples], 25
|
79
98
|
end
|
80
99
|
|
@@ -89,10 +108,16 @@ class StackProfTest < MiniTest::Test
|
|
89
108
|
assert_equal :custom, profile[:mode]
|
90
109
|
assert_equal 10, profile[:samples]
|
91
110
|
|
92
|
-
|
111
|
+
offset = RUBY_VERSION >= '3' ? 1 : 0
|
112
|
+
frame = profile[:frames].values[offset]
|
93
113
|
assert_includes frame[:name], "StackProfTest#test_custom"
|
94
114
|
assert_includes [profile_base_line-2, profile_base_line+1], frame[:line]
|
95
|
-
|
115
|
+
|
116
|
+
if RUBY_VERSION >= '3'
|
117
|
+
assert_equal [10, 0], frame[:lines][profile_base_line+2]
|
118
|
+
else
|
119
|
+
assert_equal [10, 10], frame[:lines][profile_base_line+2]
|
120
|
+
end
|
96
121
|
end
|
97
122
|
|
98
123
|
def test_raw
|
@@ -105,7 +130,9 @@ class StackProfTest < MiniTest::Test
|
|
105
130
|
raw = profile[:raw]
|
106
131
|
assert_equal 10, raw[-1]
|
107
132
|
assert_equal raw[0] + 2, raw.size
|
108
|
-
|
133
|
+
|
134
|
+
offset = RUBY_VERSION >= '3' ? -3 : -2
|
135
|
+
assert_includes profile[:frames][raw[offset]][:name], 'StackProfTest#test_raw'
|
109
136
|
assert_equal 10, profile[:raw_timestamp_deltas].size
|
110
137
|
end
|
111
138
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stackprof
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.17
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aman Gupta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -63,10 +63,9 @@ extensions:
|
|
63
63
|
- ext/stackprof/extconf.rb
|
64
64
|
extra_rdoc_files: []
|
65
65
|
files:
|
66
|
+
- ".github/workflows/ci.yml"
|
66
67
|
- ".gitignore"
|
67
|
-
- ".travis.yml"
|
68
68
|
- CHANGELOG.md
|
69
|
-
- Dockerfile
|
70
69
|
- Gemfile
|
71
70
|
- LICENSE
|
72
71
|
- README.md
|
@@ -95,9 +94,9 @@ licenses:
|
|
95
94
|
- MIT
|
96
95
|
metadata:
|
97
96
|
bug_tracker_uri: https://github.com/tmm1/stackprof/issues
|
98
|
-
changelog_uri: https://github.com/tmm1/stackprof/blob/v0.2.
|
99
|
-
documentation_uri: https://www.rubydoc.info/gems/stackprof/0.2.
|
100
|
-
source_code_uri: https://github.com/tmm1/stackprof/tree/v0.2.
|
97
|
+
changelog_uri: https://github.com/tmm1/stackprof/blob/v0.2.17/CHANGELOG.md
|
98
|
+
documentation_uri: https://www.rubydoc.info/gems/stackprof/0.2.17
|
99
|
+
source_code_uri: https://github.com/tmm1/stackprof/tree/v0.2.17
|
101
100
|
post_install_message:
|
102
101
|
rdoc_options: []
|
103
102
|
require_paths:
|
@@ -113,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
113
112
|
- !ruby/object:Gem::Version
|
114
113
|
version: '0'
|
115
114
|
requirements: []
|
116
|
-
rubygems_version: 3.
|
115
|
+
rubygems_version: 3.1.2
|
117
116
|
signing_key:
|
118
117
|
specification_version: 4
|
119
118
|
summary: sampling callstack-profiler for ruby 2.2+
|
data/.travis.yml
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
sudo: required
|
2
|
-
|
3
|
-
services:
|
4
|
-
- docker
|
5
|
-
|
6
|
-
language: general
|
7
|
-
|
8
|
-
env:
|
9
|
-
matrix:
|
10
|
-
- RVM_RUBY_VERSION=2.2
|
11
|
-
- RVM_RUBY_VERSION=2.3
|
12
|
-
- RVM_RUBY_VERSION=2.4
|
13
|
-
- RVM_RUBY_VERSION=2.5
|
14
|
-
- RVM_RUBY_VERSION=2.6
|
15
|
-
- RVM_RUBY_VERSION=ruby-head
|
16
|
-
|
17
|
-
before_install:
|
18
|
-
- sudo docker build -t stackprof-$RVM_RUBY_VERSION --build-arg=RVM_RUBY_VERSION=$RVM_RUBY_VERSION .
|
19
|
-
|
20
|
-
script:
|
21
|
-
- sudo docker run --name stackprof-$RVM_RUBY_VERSION stackprof-$RVM_RUBY_VERSION
|
data/Dockerfile
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
FROM ubuntu:16.04
|
2
|
-
ARG DEBIAN_FRONTEND=noninteractive
|
3
|
-
RUN apt-get update -q && \
|
4
|
-
apt-get install -qy \
|
5
|
-
curl ca-certificates gnupg2 dirmngr build-essential \
|
6
|
-
gawk git autoconf automake pkg-config \
|
7
|
-
bison libffi-dev libgdbm-dev libncurses5-dev libsqlite3-dev libtool \
|
8
|
-
libyaml-dev sqlite3 zlib1g-dev libgmp-dev libreadline-dev libssl-dev \
|
9
|
-
ruby --no-install-recommends && \
|
10
|
-
apt-get clean
|
11
|
-
|
12
|
-
RUN gpg2 --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
|
13
|
-
RUN curl -sSL https://get.rvm.io | bash -s
|
14
|
-
ARG RVM_RUBY_VERSION=ruby-head
|
15
|
-
RUN /bin/bash -l -c "echo $RVM_RUBY_VERSION"
|
16
|
-
RUN /bin/bash -l -c ". /etc/profile.d/rvm.sh && rvm install $RVM_RUBY_VERSION --binary || rvm install $RVM_RUBY_VERSION"
|
17
|
-
ADD . /stackprof/
|
18
|
-
WORKDIR /stackprof/
|
19
|
-
RUN /bin/bash -l -c ". /etc/profile.d/rvm.sh && gem install bundler:1.16.0"
|
20
|
-
RUN /bin/bash -l -c ". /etc/profile.d/rvm.sh && bundle install"
|
21
|
-
CMD /bin/bash -l -c ". /etc/profile.d/rvm.sh && bundle exec rake"
|