pf2 0.10.0 → 0.11.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 +4 -4
- data/.document +3 -0
- data/.rdoc_options +6 -0
- data/CHANGELOG.md +20 -1
- data/README.md +22 -0
- data/Rakefile +5 -0
- data/ext/pf2/pf2.c +8 -8
- data/ext/pf2/sample.c +1 -3
- data/ext/pf2/sample.h +5 -4
- data/ext/pf2/session.c +23 -2
- data/ext/pf2/session.h +1 -1
- data/lib/pf2/reporter/stack_weaver.rb +1 -1
- data/lib/pf2/version.rb +1 -1
- data/lib/pf2.rb +1 -2
- metadata +17 -2
- data/lib/pf2/session.rb +0 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 74e3ac2900007b7750e3c3274833e1f713b6e85570db0aa738761ea99b517fe8
|
|
4
|
+
data.tar.gz: 68ffc8d681328e4d5542e4bd4b3a98edfd08d69fa1b54342fdccbe8f9495bcf0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4f1e67870eac32734a7532f46f29b74589ec6d71c59c925fc02456f473a516218fbbf46fed730558f0b9525c585dbb2fbc088fcf9cbfb47e7f4b89adda7f4974
|
|
7
|
+
data.tar.gz: 8f5ec74f112eb65a512dbcd7002b0db9a4da0d3a2124d3bd2e7106412c71009b36f92ff442efc87910a5a8829094c06e1ee93169c829ab893dd8e1bd86a81a4f
|
data/.document
ADDED
data/.rdoc_options
ADDED
data/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
|
+
## [Unreleased]
|
|
2
|
+
|
|
3
|
+
## [0.11.0] - 2025-12-27
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- RDoc documentation is now online - https://osyoyu.github.io/pf2/
|
|
8
|
+
- Native stack consolidation now supports LTO-ed binaries (@hanazuki)
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- `Pf2c` module is now completely removed. `Pf2c::Session` has been merged as `Pf2::Session`.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- Fixed an bug where the program crashes when a `Pf2::Session` is GC'd before profiling starts.
|
|
17
|
+
- Fixed an bug where the program crashes when the native stack was more than 200 frames deep.
|
|
18
|
+
|
|
19
|
+
|
|
1
20
|
## [0.10.0] - 2025-12-26
|
|
2
21
|
|
|
3
|
-
|
|
22
|
+
### Added
|
|
4
23
|
|
|
5
24
|
**This version contains a complete rewrite of the profiler!**
|
|
6
25
|
|
data/README.md
CHANGED
|
@@ -3,6 +3,9 @@ Pf2
|
|
|
3
3
|
|
|
4
4
|
A experimental sampling-based profiler for Ruby 3.3+.
|
|
5
5
|
|
|
6
|
+
- GitHub: https://github.com/osyoyu/pf2
|
|
7
|
+
- Documentation: https://osyoyu.github.io/pf2/
|
|
8
|
+
|
|
6
9
|
Notable Capabilites
|
|
7
10
|
--------
|
|
8
11
|
|
|
@@ -13,6 +16,25 @@ Notable Capabilites
|
|
|
13
16
|
Usage
|
|
14
17
|
--------
|
|
15
18
|
|
|
19
|
+
### Installation
|
|
20
|
+
|
|
21
|
+
You will need a C compiler to build the native extension.
|
|
22
|
+
|
|
23
|
+
Add this line to your application's Gemfile:
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
gem 'pf2'
|
|
27
|
+
|
|
28
|
+
# When using the main branch, specify submodules: true
|
|
29
|
+
gem 'pf2', git: 'https://github.com/osyoyu/pf2.git', submodules: true
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Pf2 can be installed as a standalone CLI tool as well.
|
|
33
|
+
|
|
34
|
+
```console
|
|
35
|
+
gem install pf2
|
|
36
|
+
```
|
|
37
|
+
|
|
16
38
|
### Quickstart
|
|
17
39
|
|
|
18
40
|
Run your Ruby program through `pf2 serve`.
|
data/Rakefile
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require 'bundler/gem_tasks'
|
|
2
2
|
require 'rake/extensiontask'
|
|
3
3
|
require 'minitest/test_task'
|
|
4
|
+
require 'rdoc/task'
|
|
4
5
|
|
|
5
6
|
task default: %i[]
|
|
6
7
|
|
|
@@ -15,3 +16,7 @@ Minitest::TestTask.create(:test) do |t|
|
|
|
15
16
|
t.warning = false
|
|
16
17
|
t.test_globs = ["test/**/*_test.rb"]
|
|
17
18
|
end
|
|
19
|
+
|
|
20
|
+
RDoc::Task.new do |doc|
|
|
21
|
+
doc.rdoc_dir = "_site" # for GitHub pages
|
|
22
|
+
end
|
data/ext/pf2/pf2.c
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
#include "session.h"
|
|
4
4
|
|
|
5
|
-
VALUE
|
|
5
|
+
VALUE rb_mPf2;
|
|
6
6
|
|
|
7
7
|
RUBY_FUNC_EXPORTED void
|
|
8
8
|
Init_pf2(void)
|
|
9
9
|
{
|
|
10
|
-
|
|
11
|
-
VALUE
|
|
12
|
-
rb_define_alloc_func(
|
|
13
|
-
rb_define_method(
|
|
14
|
-
rb_define_method(
|
|
15
|
-
rb_define_method(
|
|
16
|
-
rb_define_method(
|
|
10
|
+
rb_mPf2 = rb_define_module("Pf2");
|
|
11
|
+
VALUE rb_mPf2_cSession = rb_define_class_under(rb_mPf2, "Session", rb_cObject);
|
|
12
|
+
rb_define_alloc_func(rb_mPf2_cSession, pf2_session_alloc);
|
|
13
|
+
rb_define_method(rb_mPf2_cSession, "initialize", rb_pf2_session_initialize, -1);
|
|
14
|
+
rb_define_method(rb_mPf2_cSession, "start", rb_pf2_session_start, 0);
|
|
15
|
+
rb_define_method(rb_mPf2_cSession, "stop", rb_pf2_session_stop, 0);
|
|
16
|
+
rb_define_method(rb_mPf2_cSession, "configuration", rb_pf2_session_configuration, 0);
|
|
17
17
|
}
|
data/ext/pf2/sample.c
CHANGED
|
@@ -9,8 +9,6 @@
|
|
|
9
9
|
#include "backtrace_state.h"
|
|
10
10
|
#include "sample.h"
|
|
11
11
|
|
|
12
|
-
const int PF2_SAMPLE_MAX_NATIVE_DEPTH = 300;
|
|
13
|
-
|
|
14
12
|
static int capture_native_backtrace(struct pf2_sample *sample);
|
|
15
13
|
static int backtrace_on_ok(void *data, uintptr_t pc);
|
|
16
14
|
|
|
@@ -29,7 +27,7 @@ pf2_sample_capture(struct pf2_sample *sample)
|
|
|
29
27
|
sample->context_pthread = pthread_self();
|
|
30
28
|
|
|
31
29
|
// Obtain the current stack from Ruby
|
|
32
|
-
sample->depth = rb_profile_frames(0,
|
|
30
|
+
sample->depth = rb_profile_frames(0, PF2_SAMPLE_MAX_RUBY_DEPTH, sample->cmes, sample->linenos);
|
|
33
31
|
|
|
34
32
|
// Capture C-level backtrace
|
|
35
33
|
sample->native_stack_depth = capture_native_backtrace(sample);
|
data/ext/pf2/sample.h
CHANGED
|
@@ -5,17 +5,18 @@
|
|
|
5
5
|
|
|
6
6
|
#include <ruby.h>
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
#define PF2_SAMPLE_MAX_RUBY_DEPTH 200
|
|
9
|
+
#define PF2_SAMPLE_MAX_NATIVE_DEPTH 300
|
|
9
10
|
|
|
10
11
|
struct pf2_sample {
|
|
11
12
|
pthread_t context_pthread;
|
|
12
13
|
|
|
13
14
|
int depth;
|
|
14
|
-
VALUE cmes[
|
|
15
|
-
int linenos[
|
|
15
|
+
VALUE cmes[PF2_SAMPLE_MAX_RUBY_DEPTH];
|
|
16
|
+
int linenos[PF2_SAMPLE_MAX_RUBY_DEPTH];
|
|
16
17
|
|
|
17
18
|
size_t native_stack_depth;
|
|
18
|
-
uintptr_t native_stack[
|
|
19
|
+
uintptr_t native_stack[PF2_SAMPLE_MAX_NATIVE_DEPTH];
|
|
19
20
|
|
|
20
21
|
uint64_t consumed_time_ns;
|
|
21
22
|
uint64_t timestamp_ns;
|
data/ext/pf2/session.c
CHANGED
|
@@ -318,19 +318,32 @@ pf2_session_alloc(VALUE self)
|
|
|
318
318
|
rb_raise(rb_eNoMemError, "Failed to allocate memory");
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
+
// is_running
|
|
322
|
+
session->is_running = false;
|
|
323
|
+
|
|
324
|
+
// timer
|
|
325
|
+
#ifdef HAVE_TIMER_CREATE
|
|
326
|
+
session->timer = (timer_t)0;
|
|
327
|
+
#else
|
|
328
|
+
session->timer = (struct itimerval){0};
|
|
329
|
+
#endif
|
|
330
|
+
|
|
331
|
+
// rbuf
|
|
321
332
|
session->rbuf = pf2_ringbuffer_new(1000);
|
|
322
333
|
if (session->rbuf == NULL) {
|
|
323
334
|
rb_raise(rb_eNoMemError, "Failed to allocate memory");
|
|
324
335
|
}
|
|
325
336
|
|
|
337
|
+
// is_marking
|
|
326
338
|
atomic_store_explicit(&session->is_marking, false, memory_order_relaxed);
|
|
339
|
+
|
|
340
|
+
// collector_thread
|
|
327
341
|
session->collector_thread = malloc(sizeof(pthread_t));
|
|
328
342
|
if (session->collector_thread == NULL) {
|
|
329
343
|
rb_raise(rb_eNoMemError, "Failed to allocate memory");
|
|
330
344
|
}
|
|
331
345
|
|
|
332
|
-
|
|
333
|
-
|
|
346
|
+
// samples, samples_index, samples_capacity
|
|
334
347
|
session->samples_index = 0;
|
|
335
348
|
session->samples_capacity = 500; // 10 seconds worth of samples at 50 Hz
|
|
336
349
|
session->samples = malloc(sizeof(struct pf2_sample) * session->samples_capacity);
|
|
@@ -338,6 +351,14 @@ pf2_session_alloc(VALUE self)
|
|
|
338
351
|
rb_raise(rb_eNoMemError, "Failed to allocate memory");
|
|
339
352
|
}
|
|
340
353
|
|
|
354
|
+
// start_time_realtime, start_time
|
|
355
|
+
session->start_time_realtime = (struct timespec){0};
|
|
356
|
+
session->start_time = (struct timespec){0};
|
|
357
|
+
|
|
358
|
+
// duration_ns
|
|
359
|
+
session->duration_ns = 0;
|
|
360
|
+
|
|
361
|
+
// configuration
|
|
341
362
|
session->configuration = NULL;
|
|
342
363
|
|
|
343
364
|
return TypedData_Wrap_Struct(self, &pf2_session_type, session);
|
data/ext/pf2/session.h
CHANGED
|
@@ -43,7 +43,7 @@ void pf2_session_dfree(void *sess);
|
|
|
43
43
|
size_t pf2_session_dsize(const void *sess);
|
|
44
44
|
|
|
45
45
|
static const rb_data_type_t pf2_session_type = {
|
|
46
|
-
.wrap_struct_name = "
|
|
46
|
+
.wrap_struct_name = "Pf2::Session",
|
|
47
47
|
.function = {
|
|
48
48
|
.dmark = pf2_session_dmark,
|
|
49
49
|
.dfree = pf2_session_dfree,
|
data/lib/pf2/version.rb
CHANGED
data/lib/pf2.rb
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative 'pf2/pf2'
|
|
4
|
-
require_relative 'pf2/session'
|
|
5
4
|
require_relative 'pf2/version'
|
|
6
5
|
|
|
7
6
|
module Pf2
|
|
8
7
|
class Error < StandardError; end
|
|
9
8
|
|
|
10
9
|
def self.start(...)
|
|
11
|
-
@@session =
|
|
10
|
+
@@session = Session.new(...)
|
|
12
11
|
@@session.start
|
|
13
12
|
end
|
|
14
13
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: pf2
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daisuke Aritomo
|
|
@@ -93,6 +93,20 @@ dependencies:
|
|
|
93
93
|
- - ">="
|
|
94
94
|
- !ruby/object:Gem::Version
|
|
95
95
|
version: '0'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: rdoc
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - ">="
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
96
110
|
email:
|
|
97
111
|
- osyoyu@osyoyu.com
|
|
98
112
|
executables:
|
|
@@ -101,6 +115,8 @@ extensions:
|
|
|
101
115
|
- ext/pf2/extconf.rb
|
|
102
116
|
extra_rdoc_files: []
|
|
103
117
|
files:
|
|
118
|
+
- ".document"
|
|
119
|
+
- ".rdoc_options"
|
|
104
120
|
- CHANGELOG.md
|
|
105
121
|
- LICENSE.txt
|
|
106
122
|
- README.md
|
|
@@ -132,7 +148,6 @@ files:
|
|
|
132
148
|
- lib/pf2/reporter/firefox_profiler_ser2.rb
|
|
133
149
|
- lib/pf2/reporter/stack_weaver.rb
|
|
134
150
|
- lib/pf2/serve.rb
|
|
135
|
-
- lib/pf2/session.rb
|
|
136
151
|
- lib/pf2/version.rb
|
|
137
152
|
- vendor/libbacktrace/.gitignore
|
|
138
153
|
- vendor/libbacktrace/Isaac.Newton-Opticks.txt
|