stackprofx 0.2.7
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/.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 */
|