stackprof 0.2.22 → 0.2.24
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/bin/stackprof +15 -16
- data/ext/stackprof/stackprof.c +35 -1
- data/lib/stackprof.rb +6 -1
- data/stackprof.gemspec +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 90e33127951d53147b6a65704446ec812999df9525d868865029ee1c7450445d
|
4
|
+
data.tar.gz: 19a5f104482f355cb1957b71b18b15b9ca9bb981cfcc109688366e53704c5711
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17610238200852f97afcc730efd9171c46c3a001ff7d5b82cb65fc92f96d9d2b206474bcecc7eeee1981365d2a07fd4dad460edc54a8bc9c8b1e6c7412f7cde3
|
7
|
+
data.tar.gz: 35cc1394b526edd0782468b06d54f66eb1ff10e5741becf486f68f0b141511fad9db622816004a4ae2e1a59cff048abe2d5697848eff127640663e9246f33cca
|
data/bin/stackprof
CHANGED
@@ -2,31 +2,33 @@
|
|
2
2
|
require 'optparse'
|
3
3
|
require 'stackprof'
|
4
4
|
|
5
|
+
banner = <<-END
|
6
|
+
Usage: stackprof run [--mode=MODE|--out=FILE|--interval=INTERVAL|--format=FORMAT] -- COMMAND
|
7
|
+
Usage: stackprof [file.dump]+ [--text|--method=NAME|--callgrind|--graphviz]
|
8
|
+
END
|
9
|
+
|
5
10
|
if ARGV.first == "run"
|
6
11
|
ARGV.shift
|
7
12
|
env = {}
|
8
|
-
parser = OptionParser.new(
|
9
|
-
o.
|
10
|
-
o.banner = "Usage: stackprof [file.dump]+ [--text|--method=NAME|--callgrind|--graphviz]"
|
11
|
-
|
12
|
-
o.on('--mode', 'Mode of sampling: cpu, wall, object, default to wall') do |mode|
|
13
|
+
parser = OptionParser.new(banner) do |o|
|
14
|
+
o.on('--mode [MODE]', String, 'Mode of sampling: cpu, wall, object, default to wall') do |mode|
|
13
15
|
env["STACKPROF_MODE"] = mode
|
14
16
|
end
|
15
17
|
|
16
|
-
o.on('--out', 'The target file, which will be overwritten. Defaults to a random temporary file') do |out|
|
18
|
+
o.on('--out [FILENAME]', String, 'The target file, which will be overwritten. Defaults to a random temporary file') do |out|
|
17
19
|
env['STACKPROF_OUT'] = out
|
18
20
|
end
|
19
21
|
|
20
|
-
o.on('--interval', 'Mode-relative sample rate') do |interval|
|
21
|
-
env['STACKPROF_INTERVAL'] =
|
22
|
+
o.on('--interval [MILLISECONDS]', Integer, 'Mode-relative sample rate') do |interval|
|
23
|
+
env['STACKPROF_INTERVAL'] = interval.to_s
|
22
24
|
end
|
23
25
|
|
24
|
-
o.on('--raw', 'collects the extra data required by the --flamegraph and --stackcollapse report types') do
|
25
|
-
env['STACKPROF_RAW'] =
|
26
|
+
o.on('--raw', 'collects the extra data required by the --flamegraph and --stackcollapse report types') do |raw|
|
27
|
+
env['STACKPROF_RAW'] = raw.to_s
|
26
28
|
end
|
27
29
|
|
28
|
-
o.on('--ignore-gc', 'Ignore garbage collection frames') do
|
29
|
-
env['STACKPROF_IGNORE_GC'] =
|
30
|
+
o.on('--ignore-gc', 'Ignore garbage collection frames') do |gc|
|
31
|
+
env['STACKPROF_IGNORE_GC'] = gc.to_s
|
30
32
|
end
|
31
33
|
end
|
32
34
|
parser.parse!
|
@@ -37,10 +39,7 @@ if ARGV.first == "run"
|
|
37
39
|
else
|
38
40
|
options = {}
|
39
41
|
|
40
|
-
parser = OptionParser.new(
|
41
|
-
o.banner = "Usage: stackprof run [--mode|--out|--interval] -- COMMAND"
|
42
|
-
o.banner = "Usage: stackprof [file.dump]+ [--text|--method=NAME|--callgrind|--graphviz]"
|
43
|
-
|
42
|
+
parser = OptionParser.new(banner) do |o|
|
44
43
|
o.on('--text', 'Text summary per method (default)'){ options[:format] = :text }
|
45
44
|
o.on('--json', 'JSON output (use with web viewers)'){ options[:format] = :json }
|
46
45
|
o.on('--files', 'List of files'){ |f| options[:format] = :files }
|
data/ext/stackprof/stackprof.c
CHANGED
@@ -12,6 +12,7 @@
|
|
12
12
|
#include <ruby/st.h>
|
13
13
|
#include <ruby/io.h>
|
14
14
|
#include <ruby/intern.h>
|
15
|
+
#include <ruby/vm.h>
|
15
16
|
#include <signal.h>
|
16
17
|
#include <sys/time.h>
|
17
18
|
#include <time.h>
|
@@ -32,6 +33,7 @@ static const char *fake_frame_cstrs[] = {
|
|
32
33
|
};
|
33
34
|
|
34
35
|
static int stackprof_use_postponed_job = 1;
|
36
|
+
static int ruby_vm_running = 0;
|
35
37
|
|
36
38
|
#define TOTAL_FAKE_FRAMES (sizeof(fake_frame_cstrs) / sizeof(char *))
|
37
39
|
|
@@ -125,6 +127,8 @@ static struct {
|
|
125
127
|
sample_time_t buffer_time;
|
126
128
|
VALUE frames_buffer[BUF_SIZE];
|
127
129
|
int lines_buffer[BUF_SIZE];
|
130
|
+
|
131
|
+
pthread_t target_thread;
|
128
132
|
} _stackprof;
|
129
133
|
|
130
134
|
static VALUE sym_object, sym_wall, sym_cpu, sym_custom, sym_name, sym_file, sym_line;
|
@@ -219,6 +223,7 @@ stackprof_start(int argc, VALUE *argv, VALUE self)
|
|
219
223
|
_stackprof.ignore_gc = ignore_gc;
|
220
224
|
_stackprof.metadata = metadata;
|
221
225
|
_stackprof.out = out;
|
226
|
+
_stackprof.target_thread = pthread_self();
|
222
227
|
|
223
228
|
if (raw) {
|
224
229
|
capture_timestamp(&_stackprof.last_sample_at);
|
@@ -721,7 +726,27 @@ stackprof_signal_handler(int sig, siginfo_t *sinfo, void *ucontext)
|
|
721
726
|
_stackprof.overall_signals++;
|
722
727
|
|
723
728
|
if (!_stackprof.running) return;
|
724
|
-
|
729
|
+
|
730
|
+
// There's a possibility that the signal handler is invoked *after* the Ruby
|
731
|
+
// VM has been shut down (e.g. after ruby_cleanup(0)). In this case, things
|
732
|
+
// that rely on global VM state (e.g. rb_during_gc) will segfault.
|
733
|
+
if (!ruby_vm_running) return;
|
734
|
+
|
735
|
+
if (_stackprof.mode == sym_wall) {
|
736
|
+
// In "wall" mode, the SIGALRM signal will arrive at an arbitrary thread.
|
737
|
+
// In order to provide more useful results, especially under threaded web
|
738
|
+
// servers, we want to forward this signal to the original thread
|
739
|
+
// StackProf was started from.
|
740
|
+
// According to POSIX.1-2008 TC1 pthread_kill and pthread_self should be
|
741
|
+
// async-signal-safe.
|
742
|
+
if (pthread_self() != _stackprof.target_thread) {
|
743
|
+
pthread_kill(_stackprof.target_thread, sig);
|
744
|
+
return;
|
745
|
+
}
|
746
|
+
} else {
|
747
|
+
if (!ruby_native_thread_p()) return;
|
748
|
+
}
|
749
|
+
|
725
750
|
if (pthread_mutex_trylock(&lock)) return;
|
726
751
|
|
727
752
|
if (!_stackprof.ignore_gc && rb_during_gc()) {
|
@@ -827,6 +852,12 @@ stackprof_use_postponed_job_l(VALUE self)
|
|
827
852
|
return Qnil;
|
828
853
|
}
|
829
854
|
|
855
|
+
static void
|
856
|
+
stackprof_at_exit(ruby_vm_t* vm)
|
857
|
+
{
|
858
|
+
ruby_vm_running = 0;
|
859
|
+
}
|
860
|
+
|
830
861
|
void
|
831
862
|
Init_stackprof(void)
|
832
863
|
{
|
@@ -837,6 +868,9 @@ Init_stackprof(void)
|
|
837
868
|
*/
|
838
869
|
stackprof_use_postponed_job = RUBY_API_VERSION_MAJOR < 3;
|
839
870
|
|
871
|
+
ruby_vm_running = 1;
|
872
|
+
ruby_vm_at_exit(stackprof_at_exit);
|
873
|
+
|
840
874
|
#define S(name) sym_##name = ID2SYM(rb_intern(#name));
|
841
875
|
S(object);
|
842
876
|
S(custom);
|
data/lib/stackprof.rb
CHANGED
@@ -6,10 +6,15 @@ end
|
|
6
6
|
|
7
7
|
if defined?(RubyVM::YJIT) && RubyVM::YJIT.enabled?
|
8
8
|
StackProf.use_postponed_job!
|
9
|
+
elsif RUBY_VERSION == "3.2.0"
|
10
|
+
# 3.2.0 crash is the signal is received at the wrong time.
|
11
|
+
# Fixed in https://github.com/ruby/ruby/pull/7116
|
12
|
+
# The fix is backported in 3.2.1: https://bugs.ruby-lang.org/issues/19336
|
13
|
+
StackProf.use_postponed_job!
|
9
14
|
end
|
10
15
|
|
11
16
|
module StackProf
|
12
|
-
VERSION = '0.2.
|
17
|
+
VERSION = '0.2.24'
|
13
18
|
end
|
14
19
|
|
15
20
|
StackProf.autoload :Report, "stackprof/report.rb"
|
data/stackprof.gemspec
CHANGED
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.24
|
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: 2023-03-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake-compiler
|
@@ -99,9 +99,9 @@ licenses:
|
|
99
99
|
- MIT
|
100
100
|
metadata:
|
101
101
|
bug_tracker_uri: https://github.com/tmm1/stackprof/issues
|
102
|
-
changelog_uri: https://github.com/tmm1/stackprof/blob/v0.2.
|
103
|
-
documentation_uri: https://www.rubydoc.info/gems/stackprof/0.2.
|
104
|
-
source_code_uri: https://github.com/tmm1/stackprof/tree/v0.2.
|
102
|
+
changelog_uri: https://github.com/tmm1/stackprof/blob/v0.2.24/CHANGELOG.md
|
103
|
+
documentation_uri: https://www.rubydoc.info/gems/stackprof/0.2.24
|
104
|
+
source_code_uri: https://github.com/tmm1/stackprof/tree/v0.2.24
|
105
105
|
post_install_message:
|
106
106
|
rdoc_options: []
|
107
107
|
require_paths:
|