stackprofx 0.2.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +24 -0
- data/README.md +41 -0
- data/Rakefile +31 -0
- data/ext/extconf.rb +11 -0
- data/ext/ruby_headers/215/id.h +171 -0
- data/ext/ruby_headers/215/internal.h +889 -0
- data/ext/ruby_headers/215/iseq.h +136 -0
- data/ext/ruby_headers/215/method.h +142 -0
- data/ext/ruby_headers/215/node.h +543 -0
- data/ext/ruby_headers/215/ruby_atomic.h +170 -0
- data/ext/ruby_headers/215/thread_native.h +23 -0
- data/ext/ruby_headers/215/thread_pthread.h +56 -0
- data/ext/ruby_headers/215/thread_win32.h +45 -0
- data/ext/ruby_headers/215/vm_core.h +1042 -0
- data/ext/ruby_headers/215/vm_debug.h +37 -0
- data/ext/ruby_headers/215/vm_opts.h +56 -0
- data/ext/stackprofx.c +622 -0
- data/sample.rb +34 -0
- data/stackprofx.gemspec +20 -0
- data/test/test_stackprofx.rb +158 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: cbd3a8e7a7a7dde3f91874113ec6cd5eeb5955c1
|
4
|
+
data.tar.gz: f9d25bff1ee930d20226b7f49ae5e86867a8f65d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 07f7a89bc6a6b9caced764466211211772edcd076709651a3aaa8c40f84eb986da693de96b451082f74f9a2908e611e7f6c70f8377cc23fc716b68ece2d559da
|
7
|
+
data.tar.gz: c6ad71cd61496d7959116d5a4afa444c2705cf51128e42f41555cea4a31cc09e8264314a4b53a5096118d7e56ab92c6211e482fe2be786cc6f91739ed078a6d0
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
stackprofx (0.2.7)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
metaclass (0.0.4)
|
10
|
+
minitest (5.4.1)
|
11
|
+
mocha (0.14.0)
|
12
|
+
metaclass (~> 0.0.1)
|
13
|
+
rake (10.3.2)
|
14
|
+
rake-compiler (0.9.3)
|
15
|
+
rake
|
16
|
+
|
17
|
+
PLATFORMS
|
18
|
+
ruby
|
19
|
+
|
20
|
+
DEPENDENCIES
|
21
|
+
minitest (~> 5.0)
|
22
|
+
mocha (~> 0.14)
|
23
|
+
rake-compiler (~> 0.9)
|
24
|
+
stackprofx!
|
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
## stackprofx
|
2
|
+
|
3
|
+
Stackprofx is a fork of the sampling call-stack profiler for Ruby 2.1+,
|
4
|
+
[`stackprof`][1]. It exists only because the fork's author wanted to
|
5
|
+
make some terrible changes to the upstream project that no maintainer
|
6
|
+
should accept.
|
7
|
+
|
8
|
+
### Why "x"?
|
9
|
+
|
10
|
+
I was considering calling it stackprof2, but 2 implies a successor to 1
|
11
|
+
and this is in no way "better" than the original project.
|
12
|
+
|
13
|
+
[1]: https://github.com/tmm1/stackprof
|
14
|
+
|
15
|
+
### What changes?
|
16
|
+
|
17
|
+
`StackProf::run` accepts an options hash to specify profiling parameters.
|
18
|
+
Stackprofx adds one more (optional) key: `:threads`. The value for `:threads`
|
19
|
+
should be an array of [`Thread`][1] objects to be profiled. All other threads
|
20
|
+
will be ignored.
|
21
|
+
|
22
|
+
Even if the `:threads` key is not specified, the behaviour of Stackprofx is
|
23
|
+
slightly different. `stackprof` makes use of the `rb_profile_frames()` function
|
24
|
+
added to MRI 2.1, but this thread is [limited][2] to only profiling whatever
|
25
|
+
happens to be the "current thread" when the profiling signal is received by
|
26
|
+
the Ruby process. Stackprofx will profile every running thread.
|
27
|
+
|
28
|
+
To do this, Stackprofx pulls in a bunch of private Ruby headers and reimplements
|
29
|
+
(copypasta) this function with one additional parameter: thread. This might
|
30
|
+
(probably will) break in the future, but it's for development, not production,
|
31
|
+
right?
|
32
|
+
|
33
|
+
[1]: http://ruby-doc.org/core-2.1.5/Thread.html
|
34
|
+
[2]: https://bugs.ruby-lang.org/issues/10602
|
35
|
+
|
36
|
+
### TODO
|
37
|
+
|
38
|
+
* Investigate terrible hacks required to link against Ruby
|
39
|
+
* Make stack deduplication (weights) useful again
|
40
|
+
* Less mess
|
41
|
+
* Ask someone who knows something about the Ruby GC to review
|
data/Rakefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
task :default => :test
|
2
|
+
|
3
|
+
# ==========================================================
|
4
|
+
# Packaging
|
5
|
+
# ==========================================================
|
6
|
+
|
7
|
+
GEMSPEC = Gem::Specification::load('stackprofx.gemspec')
|
8
|
+
|
9
|
+
require 'rubygems/package_task'
|
10
|
+
Gem::PackageTask.new(GEMSPEC) do |pkg|
|
11
|
+
end
|
12
|
+
|
13
|
+
# ==========================================================
|
14
|
+
# Ruby Extension
|
15
|
+
# ==========================================================
|
16
|
+
|
17
|
+
require 'rake/extensiontask'
|
18
|
+
Rake::ExtensionTask.new('stackprofx', GEMSPEC) do |ext|
|
19
|
+
ext.ext_dir = 'ext'
|
20
|
+
end
|
21
|
+
task :build => :compile
|
22
|
+
|
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
|
data/ext/extconf.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
if have_func('rb_postponed_job_register_one') &&
|
3
|
+
have_func('rb_profile_frames') &&
|
4
|
+
have_func('rb_tracepoint_new') &&
|
5
|
+
have_const('RUBY_INTERNAL_EVENT_NEWOBJ')
|
6
|
+
|
7
|
+
$CFLAGS += " -I../../../../ext/ruby_headers/215"
|
8
|
+
create_makefile('stackprofx')
|
9
|
+
else
|
10
|
+
fail 'missing API: are you using ruby 2.1+?'
|
11
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
/* DO NOT EDIT THIS FILE DIRECTLY */
|
2
|
+
/**********************************************************************
|
3
|
+
|
4
|
+
id.h -
|
5
|
+
|
6
|
+
$Author: nobu $
|
7
|
+
created at: Sun Oct 19 21:12:51 2008
|
8
|
+
|
9
|
+
Copyright (C) 2007 Koichi Sasada
|
10
|
+
|
11
|
+
**********************************************************************/
|
12
|
+
|
13
|
+
#ifndef RUBY_ID_H
|
14
|
+
#define RUBY_ID_H
|
15
|
+
|
16
|
+
enum ruby_id_types {
|
17
|
+
RUBY_ID_LOCAL = 0x00,
|
18
|
+
RUBY_ID_INSTANCE = 0x01,
|
19
|
+
RUBY_ID_GLOBAL = 0x03,
|
20
|
+
RUBY_ID_ATTRSET = 0x04,
|
21
|
+
RUBY_ID_CONST = 0x05,
|
22
|
+
RUBY_ID_CLASS = 0x06,
|
23
|
+
RUBY_ID_JUNK = 0x07,
|
24
|
+
RUBY_ID_INTERNAL = RUBY_ID_JUNK,
|
25
|
+
RUBY_ID_SCOPE_SHIFT = 3,
|
26
|
+
RUBY_ID_SCOPE_MASK = ~(~0U<<RUBY_ID_SCOPE_SHIFT)
|
27
|
+
};
|
28
|
+
|
29
|
+
#define ID_SCOPE_SHIFT RUBY_ID_SCOPE_SHIFT
|
30
|
+
#define ID_SCOPE_MASK RUBY_ID_SCOPE_MASK
|
31
|
+
#define ID_LOCAL RUBY_ID_LOCAL
|
32
|
+
#define ID_INSTANCE RUBY_ID_INSTANCE
|
33
|
+
#define ID_GLOBAL RUBY_ID_GLOBAL
|
34
|
+
#define ID_ATTRSET RUBY_ID_ATTRSET
|
35
|
+
#define ID_CONST RUBY_ID_CONST
|
36
|
+
#define ID_CLASS RUBY_ID_CLASS
|
37
|
+
#define ID_JUNK RUBY_ID_JUNK
|
38
|
+
#define ID_INTERNAL RUBY_ID_INTERNAL
|
39
|
+
|
40
|
+
#define ID2ATTRSET(id) (((id)&~ID_SCOPE_MASK)|ID_ATTRSET)
|
41
|
+
|
42
|
+
#define symIFUNC ID2SYM(idIFUNC)
|
43
|
+
#define symCFUNC ID2SYM(idCFUNC)
|
44
|
+
|
45
|
+
#define RUBY_TOKEN_DOT2 128
|
46
|
+
#define RUBY_TOKEN_DOT3 129
|
47
|
+
#define RUBY_TOKEN_UPLUS 130
|
48
|
+
#define RUBY_TOKEN_UMINUS 131
|
49
|
+
#define RUBY_TOKEN_POW 132
|
50
|
+
#define RUBY_TOKEN_DSTAR 133
|
51
|
+
#define RUBY_TOKEN_CMP 134
|
52
|
+
#define RUBY_TOKEN_LSHFT 135
|
53
|
+
#define RUBY_TOKEN_RSHFT 136
|
54
|
+
#define RUBY_TOKEN_LEQ 137
|
55
|
+
#define RUBY_TOKEN_GEQ 138
|
56
|
+
#define RUBY_TOKEN_EQ 139
|
57
|
+
#define RUBY_TOKEN_EQQ 140
|
58
|
+
#define RUBY_TOKEN_NEQ 141
|
59
|
+
#define RUBY_TOKEN_MATCH 142
|
60
|
+
#define RUBY_TOKEN_NMATCH 143
|
61
|
+
#define RUBY_TOKEN_AREF 144
|
62
|
+
#define RUBY_TOKEN_ASET 145
|
63
|
+
#define RUBY_TOKEN_COLON2 146
|
64
|
+
#define RUBY_TOKEN_COLON3 147
|
65
|
+
#define RUBY_TOKEN(t) RUBY_TOKEN_##t
|
66
|
+
|
67
|
+
enum ruby_method_ids {
|
68
|
+
idDot2 = RUBY_TOKEN(DOT2),
|
69
|
+
idDot3 = RUBY_TOKEN(DOT3),
|
70
|
+
idUPlus = RUBY_TOKEN(UPLUS),
|
71
|
+
idUMinus = RUBY_TOKEN(UMINUS),
|
72
|
+
idPow = RUBY_TOKEN(POW),
|
73
|
+
idCmp = RUBY_TOKEN(CMP),
|
74
|
+
idPLUS = '+',
|
75
|
+
idMINUS = '-',
|
76
|
+
idMULT = '*',
|
77
|
+
idDIV = '/',
|
78
|
+
idMOD = '%',
|
79
|
+
idLT = '<',
|
80
|
+
idLTLT = RUBY_TOKEN(LSHFT),
|
81
|
+
idLE = RUBY_TOKEN(LEQ),
|
82
|
+
idGT = '>',
|
83
|
+
idGE = RUBY_TOKEN(GEQ),
|
84
|
+
idEq = RUBY_TOKEN(EQ),
|
85
|
+
idEqq = RUBY_TOKEN(EQQ),
|
86
|
+
idNeq = RUBY_TOKEN(NEQ),
|
87
|
+
idNot = '!',
|
88
|
+
idBackquote = '`',
|
89
|
+
idEqTilde = RUBY_TOKEN(MATCH),
|
90
|
+
idNeqTilde = RUBY_TOKEN(NMATCH),
|
91
|
+
idAREF = RUBY_TOKEN(AREF),
|
92
|
+
idASET = RUBY_TOKEN(ASET),
|
93
|
+
tPRESERVED_ID_BEGIN = 147,
|
94
|
+
idNULL,
|
95
|
+
idEmptyP,
|
96
|
+
idEqlP,
|
97
|
+
idRespond_to,
|
98
|
+
idRespond_to_missing,
|
99
|
+
idIFUNC,
|
100
|
+
idCFUNC,
|
101
|
+
id_core_set_method_alias,
|
102
|
+
id_core_set_variable_alias,
|
103
|
+
id_core_undef_method,
|
104
|
+
id_core_define_method,
|
105
|
+
id_core_define_singleton_method,
|
106
|
+
id_core_set_postexe,
|
107
|
+
id_core_hash_from_ary,
|
108
|
+
id_core_hash_merge_ary,
|
109
|
+
id_core_hash_merge_ptr,
|
110
|
+
id_core_hash_merge_kwd,
|
111
|
+
tPRESERVED_ID_END,
|
112
|
+
tFreeze,
|
113
|
+
tInspect,
|
114
|
+
tIntern,
|
115
|
+
tObject_id,
|
116
|
+
tConst_missing,
|
117
|
+
tMethodMissing,
|
118
|
+
tMethod_added,
|
119
|
+
tSingleton_method_added,
|
120
|
+
tMethod_removed,
|
121
|
+
tSingleton_method_removed,
|
122
|
+
tMethod_undefined,
|
123
|
+
tSingleton_method_undefined,
|
124
|
+
tLength,
|
125
|
+
tSize,
|
126
|
+
tGets,
|
127
|
+
tSucc,
|
128
|
+
tEach,
|
129
|
+
tProc,
|
130
|
+
tLambda,
|
131
|
+
tSend,
|
132
|
+
t__send__,
|
133
|
+
t__attached__,
|
134
|
+
tInitialize,
|
135
|
+
tInitialize_copy,
|
136
|
+
tInitialize_clone,
|
137
|
+
tInitialize_dup,
|
138
|
+
tUScore,
|
139
|
+
#define TOKEN2LOCALID(n) id##n = ((t##n<<ID_SCOPE_SHIFT)|ID_LOCAL)
|
140
|
+
TOKEN2LOCALID(Freeze),
|
141
|
+
TOKEN2LOCALID(Inspect),
|
142
|
+
TOKEN2LOCALID(Intern),
|
143
|
+
TOKEN2LOCALID(Object_id),
|
144
|
+
TOKEN2LOCALID(Const_missing),
|
145
|
+
TOKEN2LOCALID(MethodMissing),
|
146
|
+
TOKEN2LOCALID(Method_added),
|
147
|
+
TOKEN2LOCALID(Singleton_method_added),
|
148
|
+
TOKEN2LOCALID(Method_removed),
|
149
|
+
TOKEN2LOCALID(Singleton_method_removed),
|
150
|
+
TOKEN2LOCALID(Method_undefined),
|
151
|
+
TOKEN2LOCALID(Singleton_method_undefined),
|
152
|
+
TOKEN2LOCALID(Length),
|
153
|
+
TOKEN2LOCALID(Size),
|
154
|
+
TOKEN2LOCALID(Gets),
|
155
|
+
TOKEN2LOCALID(Succ),
|
156
|
+
TOKEN2LOCALID(Each),
|
157
|
+
TOKEN2LOCALID(Proc),
|
158
|
+
TOKEN2LOCALID(Lambda),
|
159
|
+
TOKEN2LOCALID(Send),
|
160
|
+
TOKEN2LOCALID(__send__),
|
161
|
+
TOKEN2LOCALID(__attached__),
|
162
|
+
TOKEN2LOCALID(Initialize),
|
163
|
+
TOKEN2LOCALID(Initialize_copy),
|
164
|
+
TOKEN2LOCALID(Initialize_clone),
|
165
|
+
TOKEN2LOCALID(Initialize_dup),
|
166
|
+
TOKEN2LOCALID(UScore),
|
167
|
+
tLAST_OP_ID = tPRESERVED_ID_END-1,
|
168
|
+
idLAST_OP_ID = tLAST_OP_ID >> ID_SCOPE_SHIFT
|
169
|
+
};
|
170
|
+
|
171
|
+
#endif /* RUBY_ID_H */
|