stackprof 0.2.7 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile.lock +6 -4
- data/LICENSE +21 -0
- data/README.md +15 -3
- data/bin/stackprof +18 -7
- data/ext/stackprof.c +2 -1
- data/lib/stackprof/middleware.rb +3 -2
- data/lib/stackprof/report.rb +35 -14
- data/sample.rb +1 -1
- data/stackprof.gemspec +2 -1
- data/test/test_middleware.rb +7 -3
- data/test/test_report.rb +34 -0
- data/test/test_stackprof.rb +17 -25
- metadata +28 -19
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8cdda351beb1c3d9ec3ea54b3b5ba337c7fee2b4
|
4
|
+
data.tar.gz: 723685a77ea3e6353415f450b01482a02a9cb2c5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cc644c9cff62e83ecb6f38e714b204780d5ca47e16293c9265eff6acbc2a242722ba035b135b9f2557fab9bc8c969f1a2a31ff8e02d9bbd45b2f62466e2949f4
|
7
|
+
data.tar.gz: 29d719e15d94559440af70bb0e02eafcad996cfeee37890377cd834cb81e01373378618c4aba60e727a81b5dffcf7511e37e35c0b5aae54cecdcf82a936017c8
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,22 +1,24 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
stackprof (0.2.
|
4
|
+
stackprof (0.2.7)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
-
metaclass (0.0.
|
9
|
+
metaclass (0.0.4)
|
10
|
+
minitest (5.4.1)
|
10
11
|
mocha (0.14.0)
|
11
12
|
metaclass (~> 0.0.1)
|
12
|
-
rake (10.
|
13
|
-
rake-compiler (0.9.
|
13
|
+
rake (10.3.2)
|
14
|
+
rake-compiler (0.9.3)
|
14
15
|
rake
|
15
16
|
|
16
17
|
PLATFORMS
|
17
18
|
ruby
|
18
19
|
|
19
20
|
DEPENDENCIES
|
21
|
+
minitest (~> 5.0)
|
20
22
|
mocha (~> 0.14)
|
21
23
|
rake-compiler (~> 0.9)
|
22
24
|
stackprof!
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013-2015 Aman Gupta
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
@@ -186,7 +186,7 @@ digraph profile {
|
|
186
186
|
}
|
187
187
|
```
|
188
188
|
|
189
|
-
#### `StackProf::Report.new(data).
|
189
|
+
#### `StackProf::Report.new(data).print_method(/pow|newobj|math/)`
|
190
190
|
|
191
191
|
```
|
192
192
|
A#pow (/Users/tmm1/code/stackprof/sample.rb:11)
|
@@ -265,11 +265,23 @@ multiple start/stop invocations.
|
|
265
265
|
|
266
266
|
``` ruby
|
267
267
|
StackProf.running?
|
268
|
-
StackProf.start
|
268
|
+
StackProf.start(mode: :cpu)
|
269
269
|
StackProf.stop
|
270
|
-
StackProf.results
|
270
|
+
StackProf.results('/tmp/some.file')
|
271
271
|
```
|
272
272
|
|
273
|
+
### all options
|
274
|
+
|
275
|
+
`StackProf.run` accepts an options hash. Currently, the following options are recognized:
|
276
|
+
|
277
|
+
Option | Meaning
|
278
|
+
------- | ---------
|
279
|
+
`mode` | mode of sampling: `:cpu`, `:wall`, `:object`, or `:custom` [c.f.](#sampling)
|
280
|
+
`out` | the target file, which will be overwritten
|
281
|
+
`interval` | mode-relative sample rate [c.f.](#sampling)
|
282
|
+
`aggregate` | defaults: `true` - if `false` disables [aggregation](#aggregation)
|
283
|
+
`raw` | defaults `false` - if `true` collects the extra data required by the `--flamegraph` and `--stackcollapse` report types
|
284
|
+
|
273
285
|
### todo
|
274
286
|
|
275
287
|
* file/iseq blacklist
|
data/bin/stackprof
CHANGED
@@ -2,23 +2,20 @@
|
|
2
2
|
require 'optparse'
|
3
3
|
require 'stackprof'
|
4
4
|
|
5
|
-
options = {
|
6
|
-
:format => :text,
|
7
|
-
:sort => false,
|
8
|
-
:limit => 30
|
9
|
-
}
|
5
|
+
options = {}
|
10
6
|
|
11
7
|
parser = OptionParser.new(ARGV) do |o|
|
12
8
|
o.banner = "Usage: stackprof [file.dump]+ [--text|--method=NAME|--callgrind|--graphviz]"
|
13
9
|
|
14
10
|
o.on('--text', 'Text summary per method (default)'){ options[:format] = :text }
|
15
11
|
o.on('--files', 'List of files'){ |f| options[:format] = :files }
|
16
|
-
o.on('--limit [num]', Integer, 'Limit --text or --
|
12
|
+
o.on('--limit [num]', Integer, 'Limit --text, --files, or --graphviz output to N entries'){ |n| options[:limit] = n }
|
17
13
|
o.on('--sort-total', "Sort --text or --files output on total samples\n\n"){ options[:sort] = true }
|
18
14
|
o.on('--method [grep]', 'Zoom into specified method'){ |f| options[:format] = :method; options[:filter] = f }
|
19
15
|
o.on('--file [grep]', "Show annotated code for specified file\n\n"){ |f| options[:format] = :file; options[:filter] = f }
|
20
16
|
o.on('--callgrind', 'Callgrind output (use with kcachegrind, stackprof-gprof2dot.py)'){ options[:format] = :callgrind }
|
21
17
|
o.on('--graphviz', "Graphviz output (use with dot)"){ options[:format] = :graphviz }
|
18
|
+
o.on('--node-fraction [frac]', OptionParser::DecimalNumeric, 'Drop nodes representing less than [frac] fraction of samples'){ |n| options[:node_fraction] = n }
|
22
19
|
o.on('--stackcollapse', 'stackcollapse.pl compatible output (use with stackprof-flamegraph.pl)'){ options[:format] = :stackcollapse }
|
23
20
|
o.on('--flamegraph', "timeline-flamegraph output (js)"){ options[:format] = :flamegraph }
|
24
21
|
o.on('--flamegraph-viewer [f.js]', String, "open html viewer for flamegraph output\n\n"){ |file|
|
@@ -43,6 +40,20 @@ while ARGV.size > 0
|
|
43
40
|
end
|
44
41
|
report = reports.inject(:+)
|
45
42
|
|
43
|
+
default_options = {
|
44
|
+
:format => :text,
|
45
|
+
:sort => false,
|
46
|
+
:limit => 30
|
47
|
+
}
|
48
|
+
|
49
|
+
if options[:format] == :graphviz
|
50
|
+
default_options[:limit] = 120
|
51
|
+
default_options[:node_fraction] = 0.005
|
52
|
+
end
|
53
|
+
|
54
|
+
options = default_options.merge(options)
|
55
|
+
options.delete(:limit) if options[:limit] == 0
|
56
|
+
|
46
57
|
case options[:format]
|
47
58
|
when :text
|
48
59
|
report.print_text(options[:sort], options[:limit])
|
@@ -53,7 +64,7 @@ when :dump
|
|
53
64
|
when :callgrind
|
54
65
|
report.print_callgrind
|
55
66
|
when :graphviz
|
56
|
-
report.print_graphviz
|
67
|
+
report.print_graphviz(options)
|
57
68
|
when :stackcollapse
|
58
69
|
report.print_stackcollapse
|
59
70
|
when :flamegraph
|
data/ext/stackprof.c
CHANGED
@@ -436,8 +436,9 @@ stackprof_signal_handler(int sig, siginfo_t *sinfo, void *ucontext)
|
|
436
436
|
static void
|
437
437
|
stackprof_newobj_handler(VALUE tpval, void *data)
|
438
438
|
{
|
439
|
-
/* TODO: implement interval */
|
440
439
|
_stackprof.overall_signals++;
|
440
|
+
if (RTEST(_stackprof.interval) && _stackprof.overall_signals % NUM2LONG(_stackprof.interval))
|
441
|
+
return;
|
441
442
|
stackprof_job_handler(0);
|
442
443
|
}
|
443
444
|
|
data/lib/stackprof/middleware.rb
CHANGED
@@ -9,6 +9,7 @@ module StackProf
|
|
9
9
|
|
10
10
|
Middleware.mode = options[:mode] || :cpu
|
11
11
|
Middleware.interval = options[:interval] || 1000
|
12
|
+
Middleware.raw = options[:raw] || false
|
12
13
|
Middleware.enabled = options[:enabled]
|
13
14
|
Middleware.path = options[:path] || 'tmp'
|
14
15
|
at_exit{ Middleware.save } if options[:save_at_exit]
|
@@ -16,7 +17,7 @@ module StackProf
|
|
16
17
|
|
17
18
|
def call(env)
|
18
19
|
enabled = Middleware.enabled?(env)
|
19
|
-
StackProf.start(mode: Middleware.mode, interval: Middleware.interval) if enabled
|
20
|
+
StackProf.start(mode: Middleware.mode, interval: Middleware.interval, raw: Middleware.raw) if enabled
|
20
21
|
@app.call(env)
|
21
22
|
ensure
|
22
23
|
if enabled
|
@@ -29,7 +30,7 @@ module StackProf
|
|
29
30
|
end
|
30
31
|
|
31
32
|
class << self
|
32
|
-
attr_accessor :enabled, :mode, :interval, :path
|
33
|
+
attr_accessor :enabled, :mode, :interval, :raw, :path
|
33
34
|
|
34
35
|
def enabled?(env)
|
35
36
|
if enabled.respond_to?(:call)
|
data/lib/stackprof/report.rb
CHANGED
@@ -63,12 +63,12 @@ module StackProf
|
|
63
63
|
pp @data
|
64
64
|
end
|
65
65
|
|
66
|
-
def print_dump
|
67
|
-
puts Marshal.dump(@data.reject{|k,v| k == :files })
|
66
|
+
def print_dump(f=STDOUT)
|
67
|
+
f.puts Marshal.dump(@data.reject{|k,v| k == :files })
|
68
68
|
end
|
69
69
|
|
70
70
|
def print_stackcollapse
|
71
|
-
raise "profile does not include raw samples" unless raw = data[:raw]
|
71
|
+
raise "profile does not include raw samples (add `raw: true` to collecting StackProf.run)" unless raw = data[:raw]
|
72
72
|
|
73
73
|
while len = raw.shift
|
74
74
|
frames = raw.slice!(0, len)
|
@@ -80,7 +80,7 @@ module StackProf
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def print_flamegraph(f=STDOUT, skip_common=true)
|
83
|
-
raise "profile does not include raw samples" unless raw = data[:raw]
|
83
|
+
raise "profile does not include raw samples (add `raw: true` to collecting StackProf.run)" unless raw = data[:raw]
|
84
84
|
|
85
85
|
stacks = []
|
86
86
|
max_x = 0
|
@@ -147,29 +147,43 @@ module StackProf
|
|
147
147
|
f.puts %{{"x":#{x},"y":#{y},"width":#{weight},"frame_id":#{addr},"frame":#{frame[:name].dump},"file":#{frame[:file].dump}}}
|
148
148
|
end
|
149
149
|
|
150
|
-
def print_graphviz(
|
151
|
-
if filter
|
150
|
+
def print_graphviz(options = {}, f = STDOUT)
|
151
|
+
if filter = options[:filter]
|
152
152
|
mark_stack = []
|
153
|
-
list = frames
|
153
|
+
list = frames(true)
|
154
154
|
list.each{ |addr, frame| mark_stack << addr if frame[:name] =~ filter }
|
155
155
|
while addr = mark_stack.pop
|
156
156
|
frame = list[addr]
|
157
157
|
unless frame[:marked]
|
158
|
-
|
159
|
-
mark_stack += frame[:edges].map{ |addr, weight| addr.to_s if list[addr.to_s][:total_samples] <= weight*1.2 }.compact if frame[:edges]
|
158
|
+
mark_stack += frame[:edges].map{ |addr, weight| addr if list[addr][:total_samples] <= weight*1.2 }.compact if frame[:edges]
|
160
159
|
frame[:marked] = true
|
161
160
|
end
|
162
161
|
end
|
163
162
|
list = list.select{ |addr, frame| frame[:marked] }
|
164
|
-
list.each{ |addr, frame| frame[:edges] && frame[:edges].delete_if{ |k,v| list[k
|
163
|
+
list.each{ |addr, frame| frame[:edges] && frame[:edges].delete_if{ |k,v| list[k].nil? } }
|
165
164
|
list
|
166
165
|
else
|
167
|
-
list = frames
|
166
|
+
list = frames(true)
|
168
167
|
end
|
169
168
|
|
169
|
+
|
170
|
+
limit = options[:limit]
|
171
|
+
fraction = options[:node_fraction]
|
172
|
+
|
173
|
+
included_nodes = {}
|
174
|
+
node_minimum = fraction ? (fraction * overall_samples).ceil : 0
|
175
|
+
|
170
176
|
f.puts "digraph profile {"
|
171
|
-
|
177
|
+
f.puts "Legend [shape=box,fontsize=24,shape=plaintext,label=\""
|
178
|
+
f.print "Total samples: #{overall_samples}\\l"
|
179
|
+
f.print "Showing top #{limit} nodes\\l" if limit
|
180
|
+
f.print "Dropped nodes with < #{node_minimum} samples\\l" if fraction
|
181
|
+
f.puts "\"];"
|
182
|
+
|
183
|
+
list.each_with_index do |(frame, info), index|
|
172
184
|
call, total = info.values_at(:samples, :total_samples)
|
185
|
+
break if total < node_minimum || (limit && index >= limit)
|
186
|
+
|
173
187
|
sample = ''
|
174
188
|
sample << "#{call} (%2.1f%%)\\rof " % (call*100.0/overall_samples) if call < total
|
175
189
|
sample << "#{total} (%2.1f%%)\\r" % (total*100.0/overall_samples)
|
@@ -177,8 +191,16 @@ module StackProf
|
|
177
191
|
size = (1.0 * total / overall_samples) * 2.0 + 0.5
|
178
192
|
|
179
193
|
f.puts " \"#{frame}\" [size=#{size}] [fontsize=#{fontsize}] [penwidth=\"#{size}\"] [shape=box] [label=\"#{info[:name]}\\n#{sample}\"];"
|
194
|
+
included_nodes[frame] = true
|
195
|
+
end
|
196
|
+
|
197
|
+
list.each do |frame, info|
|
198
|
+
next unless included_nodes[frame]
|
199
|
+
|
180
200
|
if edges = info[:edges]
|
181
201
|
edges.each do |edge, weight|
|
202
|
+
next unless included_nodes[edge]
|
203
|
+
|
182
204
|
size = (1.0 * weight / overall_samples) * 2.0 + 0.5
|
183
205
|
f.puts " \"#{frame}\" -> \"#{edge}\" [label=\"#{weight}\"] [weight=\"#{weight}\"] [penwidth=\"#{size}\"];"
|
184
206
|
end
|
@@ -278,8 +300,7 @@ module StackProf
|
|
278
300
|
|
279
301
|
def print_file(filter, f = STDOUT)
|
280
302
|
filter = /#{Regexp.escape filter}/ unless Regexp === filter
|
281
|
-
list = files
|
282
|
-
list.select!{ |name, lines| name =~ filter }
|
303
|
+
list = files.select{ |name, lines| name =~ filter }
|
283
304
|
list.sort_by{ |file, vals| -vals.values.inject(0){ |sum, n| sum + (n.is_a?(Array) ? n[1] : n) } }.each do |file, lines|
|
284
305
|
source_display(f, file, lines)
|
285
306
|
end
|
data/sample.rb
CHANGED
data/stackprof.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'stackprof'
|
3
|
-
s.version = '0.2.
|
3
|
+
s.version = '0.2.8'
|
4
4
|
s.homepage = 'http://github.com/tmm1/stackprof'
|
5
5
|
|
6
6
|
s.authors = 'Aman Gupta'
|
@@ -21,4 +21,5 @@ Gem::Specification.new do |s|
|
|
21
21
|
|
22
22
|
s.add_development_dependency 'rake-compiler', '~> 0.9'
|
23
23
|
s.add_development_dependency 'mocha', '~> 0.14'
|
24
|
+
s.add_development_dependency 'minitest', '~> 5.0'
|
24
25
|
end
|
data/test/test_middleware.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
$:.unshift File.expand_path('../../lib', __FILE__)
|
2
2
|
require 'stackprof'
|
3
3
|
require 'stackprof/middleware'
|
4
|
-
require '
|
4
|
+
require 'minitest/autorun'
|
5
5
|
require 'mocha/setup'
|
6
6
|
|
7
|
-
class StackProf::MiddlewareTest < Test
|
7
|
+
class StackProf::MiddlewareTest < MiniTest::Test
|
8
8
|
|
9
9
|
def test_path_default
|
10
10
|
StackProf::Middleware.new(Object.new)
|
@@ -55,9 +55,13 @@ class StackProf::MiddlewareTest < Test::Unit::TestCase
|
|
55
55
|
StackProf::Middleware.new(Object.new, enabled: enable_proc)
|
56
56
|
refute StackProf::Middleware.enabled?(env)
|
57
57
|
|
58
|
-
env = Hash.new { true}
|
58
|
+
env = Hash.new { true }
|
59
59
|
StackProf::Middleware.new(Object.new, enabled: enable_proc)
|
60
60
|
assert StackProf::Middleware.enabled?(env)
|
61
61
|
end
|
62
62
|
|
63
|
+
def test_raw
|
64
|
+
StackProf::Middleware.new(Object.new, raw: true)
|
65
|
+
assert StackProf::Middleware.raw
|
66
|
+
end
|
63
67
|
end
|
data/test/test_report.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
$:.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
require 'stackprof'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
|
5
|
+
class ReportDumpTest < MiniTest::Test
|
6
|
+
require 'stringio'
|
7
|
+
|
8
|
+
def test_dump_to_stdout
|
9
|
+
data = {}
|
10
|
+
report = StackProf::Report.new(data)
|
11
|
+
|
12
|
+
out, _err = capture_subprocess_io do
|
13
|
+
report.print_dump
|
14
|
+
end
|
15
|
+
|
16
|
+
assert_dump data, out
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_dump_to_file
|
20
|
+
data = {}
|
21
|
+
f = StringIO.new
|
22
|
+
report = StackProf::Report.new(data)
|
23
|
+
|
24
|
+
report.print_dump(f)
|
25
|
+
|
26
|
+
assert_dump data, f.string
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def assert_dump(expected, marshal_data)
|
32
|
+
assert_equal expected, Marshal.load(marshal_data)
|
33
|
+
end
|
34
|
+
end
|
data/test/test_stackprof.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
$:.unshift File.expand_path('../../lib', __FILE__)
|
2
2
|
require 'stackprof'
|
3
|
-
require '
|
3
|
+
require 'minitest/autorun'
|
4
4
|
require 'tempfile'
|
5
5
|
|
6
|
-
class StackProfTest < Test
|
6
|
+
class StackProfTest < MiniTest::Test
|
7
7
|
def test_info
|
8
8
|
profile = StackProf.run{}
|
9
9
|
assert_equal 1.1, profile[:version]
|
@@ -31,6 +31,7 @@ class StackProfTest < Test::Unit::TestCase
|
|
31
31
|
end
|
32
32
|
|
33
33
|
def test_object_allocation
|
34
|
+
profile_base_line = __LINE__+1
|
34
35
|
profile = StackProf.run(mode: :object) do
|
35
36
|
Object.new
|
36
37
|
Object.new
|
@@ -42,28 +43,24 @@ class StackProfTest < Test::Unit::TestCase
|
|
42
43
|
frame = profile[:frames].values.first
|
43
44
|
assert_equal "block in StackProfTest#test_object_allocation", frame[:name]
|
44
45
|
assert_equal 2, frame[:samples]
|
45
|
-
|
46
|
-
assert_equal
|
47
|
-
assert_equal [1, 1], frame[:lines][
|
48
|
-
assert_equal [1, 1], frame[:lines][line-9]
|
46
|
+
assert_equal profile_base_line, frame[:line]
|
47
|
+
assert_equal [1, 1], frame[:lines][profile_base_line+1]
|
48
|
+
assert_equal [1, 1], frame[:lines][profile_base_line+2]
|
49
49
|
|
50
50
|
frame = profile[:frames].values[1]
|
51
|
-
assert_equal [2, 0], frame[:lines][
|
51
|
+
assert_equal [2, 0], frame[:lines][profile_base_line]
|
52
52
|
end
|
53
53
|
|
54
|
-
def
|
55
|
-
profile = StackProf.run(mode: :
|
56
|
-
|
54
|
+
def test_object_allocation_interval
|
55
|
+
profile = StackProf.run(mode: :object, interval: 10) do
|
56
|
+
100.times { Object.new }
|
57
57
|
end
|
58
|
-
|
59
|
-
assert_operator profile[:samples], :>, 1
|
60
|
-
frame = profile[:frames].values.first
|
61
|
-
assert_equal "block in StackProfTest#math", frame[:name]
|
58
|
+
assert_equal 10, profile[:samples]
|
62
59
|
end
|
63
60
|
|
64
|
-
def
|
61
|
+
def test_cputime
|
65
62
|
profile = StackProf.run(mode: :cpu, interval: 500) do
|
66
|
-
|
63
|
+
math
|
67
64
|
end
|
68
65
|
|
69
66
|
assert_operator profile[:samples], :>, 1
|
@@ -82,6 +79,7 @@ class StackProfTest < Test::Unit::TestCase
|
|
82
79
|
end
|
83
80
|
|
84
81
|
def test_custom
|
82
|
+
profile_base_line = __LINE__+1
|
85
83
|
profile = StackProf.run(mode: :custom) do
|
86
84
|
10.times do
|
87
85
|
StackProf.sample
|
@@ -93,8 +91,8 @@ class StackProfTest < Test::Unit::TestCase
|
|
93
91
|
|
94
92
|
frame = profile[:frames].values.first
|
95
93
|
assert_equal "block (2 levels) in StackProfTest#test_custom", frame[:name]
|
96
|
-
assert_equal
|
97
|
-
assert_equal [10, 10], frame[:lines][
|
94
|
+
assert_equal profile_base_line+1, frame[:line]
|
95
|
+
assert_equal [10, 10], frame[:lines][profile_base_line+2]
|
98
96
|
end
|
99
97
|
|
100
98
|
def test_raw
|
@@ -142,7 +140,7 @@ class StackProfTest < Test::Unit::TestCase
|
|
142
140
|
assert_equal tmpfile, ret
|
143
141
|
tmpfile.rewind
|
144
142
|
profile = Marshal.load(tmpfile.read)
|
145
|
-
|
143
|
+
refute_empty profile[:frames]
|
146
144
|
end
|
147
145
|
|
148
146
|
def math
|
@@ -158,10 +156,4 @@ class StackProfTest < Test::Unit::TestCase
|
|
158
156
|
r.close
|
159
157
|
w.close
|
160
158
|
end
|
161
|
-
|
162
|
-
define_method(:bmath) do
|
163
|
-
250_000.times do
|
164
|
-
2 ** 10
|
165
|
-
end
|
166
|
-
end
|
167
159
|
end
|
metadata
CHANGED
@@ -1,48 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stackprof
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
5
|
-
prerelease:
|
4
|
+
version: 0.2.8
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Aman Gupta
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2016-01-14 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rake-compiler
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- - ~>
|
17
|
+
- - "~>"
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0.9'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- - ~>
|
24
|
+
- - "~>"
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0.9'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: mocha
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- - ~>
|
31
|
+
- - "~>"
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0.14'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- - ~>
|
38
|
+
- - "~>"
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0.14'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.0'
|
46
55
|
description: stackprof is a fast sampling profiler for ruby code, with cpu, wallclock
|
47
56
|
and object allocation samplers.
|
48
57
|
email: aman@tmm1.net
|
@@ -54,9 +63,10 @@ extensions:
|
|
54
63
|
- ext/extconf.rb
|
55
64
|
extra_rdoc_files: []
|
56
65
|
files:
|
57
|
-
- .gitignore
|
66
|
+
- ".gitignore"
|
58
67
|
- Gemfile
|
59
68
|
- Gemfile.lock
|
69
|
+
- LICENSE
|
60
70
|
- README.md
|
61
71
|
- Rakefile
|
62
72
|
- bin/stackprof
|
@@ -71,6 +81,7 @@ files:
|
|
71
81
|
- sample.rb
|
72
82
|
- stackprof.gemspec
|
73
83
|
- test/test_middleware.rb
|
84
|
+
- test/test_report.rb
|
74
85
|
- test/test_stackprof.rb
|
75
86
|
- vendor/FlameGraph/README
|
76
87
|
- vendor/FlameGraph/flamegraph.pl
|
@@ -79,27 +90,25 @@ files:
|
|
79
90
|
homepage: http://github.com/tmm1/stackprof
|
80
91
|
licenses:
|
81
92
|
- MIT
|
93
|
+
metadata: {}
|
82
94
|
post_install_message:
|
83
95
|
rdoc_options: []
|
84
96
|
require_paths:
|
85
97
|
- lib
|
86
98
|
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
-
none: false
|
88
99
|
requirements:
|
89
|
-
- -
|
100
|
+
- - ">="
|
90
101
|
- !ruby/object:Gem::Version
|
91
102
|
version: '0'
|
92
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
-
none: false
|
94
104
|
requirements:
|
95
|
-
- -
|
105
|
+
- - ">="
|
96
106
|
- !ruby/object:Gem::Version
|
97
107
|
version: '0'
|
98
108
|
requirements: []
|
99
109
|
rubyforge_project:
|
100
|
-
rubygems_version:
|
110
|
+
rubygems_version: 2.2.3
|
101
111
|
signing_key:
|
102
|
-
specification_version:
|
112
|
+
specification_version: 4
|
103
113
|
summary: sampling callstack-profiler for ruby 2.1+
|
104
114
|
test_files: []
|
105
|
-
has_rdoc:
|