stackprof 0.2.26 → 0.2.27
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +1 -1
- data/ext/stackprof/stackprof.c +41 -11
- data/lib/stackprof.rb +1 -1
- data/stackprof.gemspec +1 -1
- metadata +6 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f919a966335bef57faaa01c783e1b204c435a2ba1d35f03ff6bf33302dfe34c9
|
4
|
+
data.tar.gz: 679b2bc9c1cc4c9f89638e5ab05c864cb8e9bf10f53e6ae2047cfc835575eb5a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb21acb48e4ea36eed09b5e82bb2780941a30ce973430acb10184df16893179dfd1d8e5092d546f1814b947d0693f10d2dacd526a4383b1b61cd64f75379b3f4
|
7
|
+
data.tar.gz: '08112358f745eeacf16b4df2ca4627daccf2ee5fefc31975530859891a57049148025f36f63bd72fed1bb6a1650a0837a9a5a8e4ba6e506c912c5abdd0d9ab38'
|
data/.github/workflows/ci.yml
CHANGED
data/ext/stackprof/stackprof.c
CHANGED
@@ -91,7 +91,19 @@ typedef struct {
|
|
91
91
|
int64_t delta_usec;
|
92
92
|
} sample_time_t;
|
93
93
|
|
94
|
+
/* We need to ensure that various memory operations are visible across
|
95
|
+
* threads. Ruby doesn't offer a portable way to do this sort of detection
|
96
|
+
* across all the Ruby versions we support, so we use something that casts a
|
97
|
+
* wide net (Clang, along with ICC, defines __GNUC__). */
|
98
|
+
#if defined(__GNUC__) && defined(__ATOMIC_SEQ_CST)
|
99
|
+
#define STACKPROF_HAVE_ATOMICS 1
|
100
|
+
#else
|
101
|
+
#define STACKPROF_HAVE_ATOMICS 0
|
102
|
+
#endif
|
103
|
+
|
94
104
|
static struct {
|
105
|
+
/* Access this field with the `STACKPROF_RUNNING` macro, below, since we
|
106
|
+
* can't properly express that this field has an atomic type. */
|
95
107
|
int running;
|
96
108
|
int raw;
|
97
109
|
int aggregate;
|
@@ -133,6 +145,12 @@ static struct {
|
|
133
145
|
pthread_t target_thread;
|
134
146
|
} _stackprof;
|
135
147
|
|
148
|
+
#if STACKPROF_HAVE_ATOMICS
|
149
|
+
#define STACKPROF_RUNNING() __atomic_load_n(&_stackprof.running, __ATOMIC_ACQUIRE)
|
150
|
+
#else
|
151
|
+
#define STACKPROF_RUNNING() _stackprof.running
|
152
|
+
#endif
|
153
|
+
|
136
154
|
static VALUE sym_object, sym_wall, sym_cpu, sym_custom, sym_name, sym_file, sym_line;
|
137
155
|
static VALUE sym_samples, sym_total_samples, sym_missed_samples, sym_edges, sym_lines;
|
138
156
|
static VALUE sym_version, sym_mode, sym_interval, sym_raw, sym_raw_lines, sym_metadata, sym_frames, sym_ignore_gc, sym_out;
|
@@ -154,7 +172,7 @@ stackprof_start(int argc, VALUE *argv, VALUE self)
|
|
154
172
|
int raw = 0, aggregate = 1;
|
155
173
|
VALUE metadata_val;
|
156
174
|
|
157
|
-
if (
|
175
|
+
if (STACKPROF_RUNNING())
|
158
176
|
return Qfalse;
|
159
177
|
|
160
178
|
rb_scan_args(argc, argv, "0:", &opts);
|
@@ -217,7 +235,6 @@ stackprof_start(int argc, VALUE *argv, VALUE self)
|
|
217
235
|
rb_raise(rb_eArgError, "unknown profiler mode");
|
218
236
|
}
|
219
237
|
|
220
|
-
_stackprof.running = 1;
|
221
238
|
_stackprof.raw = raw;
|
222
239
|
_stackprof.aggregate = aggregate;
|
223
240
|
_stackprof.mode = mode;
|
@@ -226,6 +243,13 @@ stackprof_start(int argc, VALUE *argv, VALUE self)
|
|
226
243
|
_stackprof.metadata = metadata;
|
227
244
|
_stackprof.out = out;
|
228
245
|
_stackprof.target_thread = pthread_self();
|
246
|
+
/* We need to ensure previous initialization stores are visible across
|
247
|
+
* threads. */
|
248
|
+
#if STACKPROF_HAVE_ATOMICS
|
249
|
+
__atomic_store_n(&_stackprof.running, 1, __ATOMIC_SEQ_CST);
|
250
|
+
#else
|
251
|
+
_stackprof.running = 1;
|
252
|
+
#endif
|
229
253
|
|
230
254
|
if (raw) {
|
231
255
|
capture_timestamp(&_stackprof.last_sample_at);
|
@@ -240,9 +264,15 @@ stackprof_stop(VALUE self)
|
|
240
264
|
struct sigaction sa;
|
241
265
|
struct itimerval timer;
|
242
266
|
|
267
|
+
#if STACKPROF_HAVE_ATOMICS
|
268
|
+
int was_running = __atomic_exchange_n(&_stackprof.running, 0, __ATOMIC_SEQ_CST);
|
269
|
+
if (!was_running)
|
270
|
+
return Qfalse;
|
271
|
+
#else
|
243
272
|
if (!_stackprof.running)
|
244
273
|
return Qfalse;
|
245
274
|
_stackprof.running = 0;
|
275
|
+
#endif
|
246
276
|
|
247
277
|
if (_stackprof.mode == sym_object) {
|
248
278
|
rb_tracepoint_disable(objtracer);
|
@@ -351,7 +381,7 @@ stackprof_results(int argc, VALUE *argv, VALUE self)
|
|
351
381
|
{
|
352
382
|
VALUE results, frames;
|
353
383
|
|
354
|
-
if (!_stackprof.frames ||
|
384
|
+
if (!_stackprof.frames || STACKPROF_RUNNING())
|
355
385
|
return Qnil;
|
356
386
|
|
357
387
|
results = rb_hash_new();
|
@@ -455,7 +485,7 @@ stackprof_run(int argc, VALUE *argv, VALUE self)
|
|
455
485
|
static VALUE
|
456
486
|
stackprof_running_p(VALUE self)
|
457
487
|
{
|
458
|
-
return
|
488
|
+
return STACKPROF_RUNNING() ? Qtrue : Qfalse;
|
459
489
|
}
|
460
490
|
|
461
491
|
static inline frame_data_t *
|
@@ -719,7 +749,7 @@ stackprof_sample_and_record(void)
|
|
719
749
|
static void
|
720
750
|
stackprof_job_record_gc(void *data)
|
721
751
|
{
|
722
|
-
if (!
|
752
|
+
if (!STACKPROF_RUNNING()) return;
|
723
753
|
|
724
754
|
stackprof_record_gc_samples();
|
725
755
|
}
|
@@ -727,7 +757,7 @@ stackprof_job_record_gc(void *data)
|
|
727
757
|
static void
|
728
758
|
stackprof_job_sample_and_record(void *data)
|
729
759
|
{
|
730
|
-
if (!
|
760
|
+
if (!STACKPROF_RUNNING()) return;
|
731
761
|
|
732
762
|
stackprof_sample_and_record();
|
733
763
|
}
|
@@ -735,7 +765,7 @@ stackprof_job_sample_and_record(void *data)
|
|
735
765
|
static void
|
736
766
|
stackprof_job_record_buffer(void *data)
|
737
767
|
{
|
738
|
-
if (!
|
768
|
+
if (!STACKPROF_RUNNING()) return;
|
739
769
|
|
740
770
|
stackprof_record_buffer();
|
741
771
|
}
|
@@ -747,7 +777,7 @@ stackprof_signal_handler(int sig, siginfo_t *sinfo, void *ucontext)
|
|
747
777
|
|
748
778
|
_stackprof.overall_signals++;
|
749
779
|
|
750
|
-
if (!
|
780
|
+
if (!STACKPROF_RUNNING()) return;
|
751
781
|
|
752
782
|
// There's a possibility that the signal handler is invoked *after* the Ruby
|
753
783
|
// VM has been shut down (e.g. after ruby_cleanup(0)). In this case, things
|
@@ -810,7 +840,7 @@ stackprof_newobj_handler(VALUE tpval, void *data)
|
|
810
840
|
static VALUE
|
811
841
|
stackprof_sample(VALUE self)
|
812
842
|
{
|
813
|
-
if (!
|
843
|
+
if (!STACKPROF_RUNNING())
|
814
844
|
return Qfalse;
|
815
845
|
|
816
846
|
_stackprof.overall_signals++;
|
@@ -854,7 +884,7 @@ static void
|
|
854
884
|
stackprof_atfork_prepare(void)
|
855
885
|
{
|
856
886
|
struct itimerval timer;
|
857
|
-
if (
|
887
|
+
if (STACKPROF_RUNNING()) {
|
858
888
|
if (_stackprof.mode == sym_wall || _stackprof.mode == sym_cpu) {
|
859
889
|
memset(&timer, 0, sizeof(timer));
|
860
890
|
setitimer(_stackprof.mode == sym_wall ? ITIMER_REAL : ITIMER_PROF, &timer, 0);
|
@@ -866,7 +896,7 @@ static void
|
|
866
896
|
stackprof_atfork_parent(void)
|
867
897
|
{
|
868
898
|
struct itimerval timer;
|
869
|
-
if (
|
899
|
+
if (STACKPROF_RUNNING()) {
|
870
900
|
if (_stackprof.mode == sym_wall || _stackprof.mode == sym_cpu) {
|
871
901
|
timer.it_interval.tv_sec = 0;
|
872
902
|
timer.it_interval.tv_usec = NUM2LONG(_stackprof.interval);
|
data/lib/stackprof.rb
CHANGED
data/stackprof.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
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.27
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aman Gupta
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 2025-01-14 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: rake-compiler
|
@@ -85,10 +84,9 @@ licenses:
|
|
85
84
|
- MIT
|
86
85
|
metadata:
|
87
86
|
bug_tracker_uri: https://github.com/tmm1/stackprof/issues
|
88
|
-
changelog_uri: https://github.com/tmm1/stackprof/blob/v0.2.
|
89
|
-
documentation_uri: https://www.rubydoc.info/gems/stackprof/0.2.
|
90
|
-
source_code_uri: https://github.com/tmm1/stackprof/tree/v0.2.
|
91
|
-
post_install_message:
|
87
|
+
changelog_uri: https://github.com/tmm1/stackprof/blob/v0.2.27/CHANGELOG.md
|
88
|
+
documentation_uri: https://www.rubydoc.info/gems/stackprof/0.2.27
|
89
|
+
source_code_uri: https://github.com/tmm1/stackprof/tree/v0.2.27
|
92
90
|
rdoc_options: []
|
93
91
|
require_paths:
|
94
92
|
- lib
|
@@ -103,8 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
101
|
- !ruby/object:Gem::Version
|
104
102
|
version: '0'
|
105
103
|
requirements: []
|
106
|
-
rubygems_version: 3.0.
|
107
|
-
signing_key:
|
104
|
+
rubygems_version: 3.7.0.dev
|
108
105
|
specification_version: 4
|
109
106
|
summary: sampling callstack-profiler for ruby 2.2+
|
110
107
|
test_files: []
|