perf2pprof 1.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 +7 -0
- data/COPYING +1 -0
- data/README +14 -0
- data/perf2pprof +125 -0
- metadata +50 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9603c69d125a72fa9ad90e475162a41a861b17a8
|
4
|
+
data.tar.gz: 3637ac300f2cdb6432aec33a0075ae175d019ba3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 010522490230e336f1d95f07b43b7aa8362790f0105fb8df1c048d428d723bde242245d3c403a3408572bb55018fc74ba536c28044d24ebe006308e41c8ba889
|
7
|
+
data.tar.gz: 44d00a91553923573d3d7cc980a34527e0af3684468c19f3ae79edf82132b1107df86c521aa31d2ee5f4bf02bc42dfd70ce9f7f08f05e986bd0f152a459481e7
|
data/COPYING
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
This is public domain.
|
data/README
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
perf2pprof converts perf record output to gperftools CPU profile
|
2
|
+
format for analysis and visualization using excellent pprof tool.
|
3
|
+
|
4
|
+
Example:
|
5
|
+
---------
|
6
|
+
|
7
|
+
# perf record --call-graph dwarf ./slow-words-count </usr/share/dic/words
|
8
|
+
|
9
|
+
# perf2pprof --web
|
10
|
+
|
11
|
+
(or)
|
12
|
+
|
13
|
+
# perf2pprof --output slow-words-count.prof
|
14
|
+
# pprof --gv ./slow-words-count slow-words-count.prof
|
data/perf2pprof
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'set'
|
4
|
+
require 'optparse'
|
5
|
+
require 'ostruct'
|
6
|
+
require 'tempfile'
|
7
|
+
require 'shellwords'
|
8
|
+
|
9
|
+
MMAPRE = /PERF_RECORD_MMAP2.*?\[(.*?)\((.*)\) @ (\S+).*\]:\s+(\S+)\s+(.+)/
|
10
|
+
STACKRE = /\A\s+([0-9A-Fa-f]+)/
|
11
|
+
|
12
|
+
class Converter
|
13
|
+
attr_reader :first_map
|
14
|
+
|
15
|
+
def read(inp)
|
16
|
+
maps = Set.new
|
17
|
+
first_map = nil
|
18
|
+
|
19
|
+
all_stacks = []
|
20
|
+
|
21
|
+
inp.each_line do |line|
|
22
|
+
while true
|
23
|
+
line.chomp!
|
24
|
+
if line =~ /\A\S/
|
25
|
+
if line =~ MMAPRE
|
26
|
+
addr, size, off, rxp, rest = $1.to_i(0), $2.to_i(0), $3.to_i(0), $4, $5
|
27
|
+
m = [addr, size, off, rxp, rest]
|
28
|
+
first_map = m unless first_map
|
29
|
+
maps << m
|
30
|
+
end
|
31
|
+
elsif line !~ /^$/
|
32
|
+
raise "unexpected: #{line}" unless line =~ STACKRE
|
33
|
+
stack = [$1.to_i(16)+1]
|
34
|
+
while (line = inp.gets)
|
35
|
+
break unless line =~ STACKRE
|
36
|
+
stack << $1.to_i(16)
|
37
|
+
end
|
38
|
+
all_stacks << stack
|
39
|
+
next if line
|
40
|
+
end
|
41
|
+
break
|
42
|
+
end
|
43
|
+
end
|
44
|
+
@all_stacks = all_stacks
|
45
|
+
@maps = maps
|
46
|
+
@first_map = first_map
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.read(inp)
|
51
|
+
self.new.read(inp)
|
52
|
+
end
|
53
|
+
|
54
|
+
def write(outp)
|
55
|
+
procmaps = ""
|
56
|
+
@maps.to_a.sort.each do |(addr, size, off, rxp, rest)|
|
57
|
+
procmaps << "#{addr.to_s(16)}-#{(addr+size).to_s(16)} #{rxp} #{off.to_s(16)} 00:00 0 #{rest}\n"
|
58
|
+
end
|
59
|
+
|
60
|
+
# this is 64-bit cpu-profile header for pprof
|
61
|
+
hdr = %w[0x00000 0x00000 0x00003 0x00000
|
62
|
+
0x00000 0x00000 0x02710 0x00000
|
63
|
+
0x00000 0x00000].map {|s| s.to_i(0)}.pack("L<*")
|
64
|
+
|
65
|
+
outp.print hdr
|
66
|
+
|
67
|
+
@all_stacks.each do |stack|
|
68
|
+
s = stack.size
|
69
|
+
newstack = [1, s, *stack]
|
70
|
+
outp.print(newstack.pack("Q<*"))
|
71
|
+
end
|
72
|
+
|
73
|
+
outp.print([0, 1, 0].pack("Q<*"))
|
74
|
+
|
75
|
+
outp.print procmaps
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
def parse_options!
|
81
|
+
opts = OpenStruct.new
|
82
|
+
opts.perf_template = "perf script -i %s --show-mmap-events"
|
83
|
+
opts.web = false
|
84
|
+
opts.perf_data = "perf.data"
|
85
|
+
opts.opath = nil
|
86
|
+
|
87
|
+
OptionParser.new do |op|
|
88
|
+
op.on("-p", "--perf-template STRING",
|
89
|
+
"perf invokation template (#{opts.pprof_template})") do |val|
|
90
|
+
opts.perf_template = val
|
91
|
+
end
|
92
|
+
op.on("--web") do
|
93
|
+
opts.web = true
|
94
|
+
end
|
95
|
+
op.on("-i", "--input PATH", "override input file to perf (perf.data)") do |path|
|
96
|
+
opts.perf_data = path
|
97
|
+
end
|
98
|
+
op.on("-o", "--output PATH", "pprof cpu profile to output") do |path|
|
99
|
+
opts.opath = path
|
100
|
+
end
|
101
|
+
end.parse!(ARGV)
|
102
|
+
opts
|
103
|
+
end
|
104
|
+
|
105
|
+
opts = parse_options!
|
106
|
+
|
107
|
+
if (opts.web && opts.opath) || (!opts.web && !opts.opath)
|
108
|
+
puts "exactly one of --web and --output must be given"
|
109
|
+
Process.exit(1)
|
110
|
+
end
|
111
|
+
|
112
|
+
c = IO.popen(opts.perf_template % [Shellwords.escape(opts.perf_data)], "r") do |f|
|
113
|
+
Converter.read f
|
114
|
+
end
|
115
|
+
|
116
|
+
if opts.web
|
117
|
+
temp = Tempfile.new("pprof-conv")
|
118
|
+
c.write(temp)
|
119
|
+
temp.close
|
120
|
+
pprof = ENV["PPROF_PATH"] || "pprof"
|
121
|
+
args = [pprof, "--web", c.first_map.last, temp.path]
|
122
|
+
p system(*args)
|
123
|
+
else
|
124
|
+
c.write(File.open(opts.opath, "w"))
|
125
|
+
end
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: perf2pprof
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.0'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Aliaksey Kandratsenka
|
8
|
+
autorequire:
|
9
|
+
bindir: "./"
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-02-15 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |
|
14
|
+
perf2pprof converts perf record output to gperftools CPU profile
|
15
|
+
format for analysis and visualization using excellent pprof tool.
|
16
|
+
email: alk@tut.by
|
17
|
+
executables:
|
18
|
+
- perf2pprof
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- "./perf2pprof"
|
23
|
+
- COPYING
|
24
|
+
- README
|
25
|
+
- perf2pprof
|
26
|
+
homepage: https://github.com/alk/perf2pprof
|
27
|
+
licenses:
|
28
|
+
- public domain
|
29
|
+
metadata: {}
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
requirements: []
|
45
|
+
rubyforge_project:
|
46
|
+
rubygems_version: 2.2.2
|
47
|
+
signing_key:
|
48
|
+
specification_version: 4
|
49
|
+
summary: perf2pprof is adaptor from perf profiles to pprof tool
|
50
|
+
test_files: []
|