summaryrefslogtreecommitdiff
path: root/test/ruby/test_settracefunc.rb
AgeCommit message (Collapse)Author
12 daysConvert Queue and SizedQueue to rb builtinJean Boussier
A large part of `thread_sync.c` was migrated already, might as well go all the way. It also allow to remove a bunch of Rdoc commands.
2025-12-16Make tracepoints with set_trace_func or TracePoint.new ractor local (#15468)Luke Gruber
Before this change, GC'ing any Ractor object caused you to lose all enabled tracepoints across all ractors (even main). Now tracepoints are ractor-local and this doesn't happen. Internal events are still global. Fixes [Bug #19112]
2025-09-02test_settracefunc.rb: Increase a timeoutTakashi Kokubun
https://github.com/ruby/ruby/actions/runs/17413734881/job/49436975287
2025-05-15Maintain same behavior regardless of tracepoint stateAaron Patterson
Always use opt_new behavior regardless of tracepoint state. Notes: Merged: https://github.com/ruby/ruby/pull/13232
2025-04-25Deopt if iseq trace events are enabledAaron Patterson
2025-04-25Inline Class#new.Aaron Patterson
This commit inlines instructions for Class#new. To make this work, we added a new YARV instructions, `opt_new`. `opt_new` checks whether or not the `new` method is the default allocator method. If it is, it allocates the object, and pushes the instance on the stack. If not, the instruction jumps to the "slow path" method call instructions. Old instructions: ``` > ruby --dump=insns -e'Object.new' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,10)> 0000 opt_getconstant_path <ic:0 Object> ( 1)[Li] 0002 opt_send_without_block <calldata!mid:new, argc:0, ARGS_SIMPLE> 0004 leave ``` New instructions: ``` > ./miniruby --dump=insns -e'Object.new' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,10)> 0000 opt_getconstant_path <ic:0 Object> ( 1)[Li] 0002 putnil 0003 swap 0004 opt_new <calldata!mid:new, argc:0, ARGS_SIMPLE>, 11 0007 opt_send_without_block <calldata!mid:initialize, argc:0, FCALL|ARGS_SIMPLE> 0009 jump 14 0011 opt_send_without_block <calldata!mid:new, argc:0, ARGS_SIMPLE> 0013 swap 0014 pop 0015 leave ``` This commit speeds up basic object allocation (`Foo.new`) by 60%, but classes that take keyword parameters see an even bigger benefit because no hash is allocated when instantiating the object (3x to 6x faster). Here is an example that uses `Hash.new(capacity: 0)`: ``` > hyperfine "ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end'" "./ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end'" Benchmark 1: ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end' Time (mean ± σ): 1.082 s ± 0.004 s [User: 1.074 s, System: 0.008 s] Range (min … max): 1.076 s … 1.088 s 10 runs Benchmark 2: ./ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end' Time (mean ± σ): 627.9 ms ± 3.5 ms [User: 622.7 ms, System: 4.8 ms] Range (min … max): 622.7 ms … 633.2 ms 10 runs Summary ./ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end' ran 1.72 ± 0.01 times faster than ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end' ``` This commit changes the backtrace for `initialize`: ``` aaron@tc ~/g/ruby (inline-new)> cat test.rb class Foo def initialize puts caller end end def hello Foo.new end hello aaron@tc ~/g/ruby (inline-new)> ruby -v test.rb ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [arm64-darwin24] test.rb:8:in 'Class#new' test.rb:8:in 'Object#hello' test.rb:11:in '<main>' aaron@tc ~/g/ruby (inline-new)> ./miniruby -v test.rb ruby 3.5.0dev (2025-03-28T23:59:40Z inline-new c4157884e4) +PRISM [arm64-darwin24] test.rb:8:in 'Object#hello' test.rb:11:in '<main>' ``` It also increases memory usage for calls to `new` by 122 bytes: ``` aaron@tc ~/g/ruby (inline-new)> cat test.rb require "objspace" class Foo def initialize puts caller end end def hello Foo.new end puts ObjectSpace.memsize_of(RubyVM::InstructionSequence.of(method(:hello))) aaron@tc ~/g/ruby (inline-new)> make runruby RUBY_ON_BUG='gdb -x ./.gdbinit -p' ./miniruby -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -- --disable-gems ./test.rb 656 aaron@tc ~/g/ruby (inline-new)> ruby -v test.rb ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [arm64-darwin24] 544 ``` Thanks to @ko1 for coming up with this idea! Co-Authored-By: John Hawthorn <john@hawthorn.email>
2025-04-10Restore the original order of const_added and inherited callbacksXavier Noria
Originally, if a class was defined with the class keyword, the cref had a const_added callback, and the superclass an inherited callback, const_added was called first, and inherited second. This was discussed in https://bugs.ruby-lang.org/issues/21143 and an attempt at changing this order was made. While both constant assignment and inheritance have happened before these callbacks are invoked, it was deemed nice to have the same order as in C = Class.new This was mostly for alignment: In that last use case things happen at different times and therefore the order of execution is kind of obvious, whereas when the class keyword is involved, the order is opaque to the user and it is up to the interpreter. However, soon in https://bugs.ruby-lang.org/issues/21193 Matz decided to play safe and keep the existing order. This reverts commits: de097fbe5f3df105bd2a26e72db06b0f5139bc1a de48e47ddf78aba02fd9623bc7ce685540a10743 Notes: Merged: https://github.com/ruby/ruby/pull/13085
2025-03-14Invoke `inherited` callbacks before `const_added`Jean Boussier
[Misc #21143] Conceptually this makes sense and is more consistent with using the `Name = Class.new(Superclass)` alternative method. However the new class is still named before `inherited` is called. Notes: Merged: https://github.com/ruby/ruby/pull/12927
2025-03-06Fix flaky failure in TestSetTraceFunc#test_tracepoint_disable (#12854)Naoto Ono
TestSetTraceFunc#test_tracepoint_disable is a flaky and failing intermittently. Here is an example of failure logs. ``` 1) Failure: TestSetTraceFunc#test_tracepoint_disable [/home/runner/work/ruby/ruby/src/test/ruby/test_settracefunc.rb:857]: <[:foo, :disable, :foo, :disable]> expected but was <[:call, :call, :foo, :disable, :foo, :disable]>. ``` https://github.com/ruby/ruby/actions/runs/13619175633/job/38066208546?pr=12585#step:12:875 I printed values of TracePoint objects as follows, and checked the values when failing intermittently. https://github.com/ruby/ruby/blob/7f9a6fc582fb5cfd88ab73a61782f39894a37ba6/test/ruby/test_settracefunc.rb#L848 Here is the log when the TestSetTraceFunc#test_tracepoint_disable failed intermittently. `2025-03-05T09:08:37.4075411Z e: call, f: /home/runner/work/ruby/ruby/src/lib/tempfile.rb, l: 386, i: call, d: Tempfile::FinalizerManager` is an unexpected events. Thus, I modified test code so that we can filter out unexpected trace events. ``` 2025-03-05T09:08:37.4075411Z e: call, f: /home/runner/work/ruby/ruby/src/lib/tempfile.rb, l: 386, i: call, d: Tempfile::FinalizerManager 2025-03-05T09:08:37.4085009Z e: call, f: /home/runner/work/ruby/ruby/src/test/ruby/test_settracefunc.rb, l: 808, i: foo, d: TestSetTraceFunc 2025-03-05T09:08:37.4086042Z e: call, f: <internal:trace_point>, l: 295, i: disable, d: TracePoint 2025-03-05T09:08:37.4115693Z e: call, f: /home/runner/work/ruby/ruby/src/test/ruby/test_settracefunc.rb, l: 808, i: foo, d: TestSetTraceFunc 2025-03-05T09:08:37.4116734Z e: call, f: <internal:trace_point>, l: 295, i: disable, d: TracePoint ``` Notes: Merged-By: ono-max <onoto1998@gmail.com>
2025-02-13[Feature #21116] Extract RJIT as a third-party gemNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/12740
2024-11-29[Bug #20915] Fix SEGV with `TracePoint#parameters` and aliased C methodviralpraxis
The following snippet results with a SEGV: ```ruby C = Class.new do alias_method :new_to_s, :to_s end TracePoint.new(:c_call, &:parameters).enable { C.new.new_to_s } ``` at MRI 3.3.6 and ruby 3.4.0dev The root cause of the issue lies in the `rb_tracearg_parameters` function within the `RUBY_EVENT_C_RETURN` branch. Specifically, when the invoked method is an alias for a C function, `rb_method_entry_without_refinements(..., trace_arg->called_id, ...)` may return NULL. In that case we can fallback to `trace_arg->id`. Notes: Merged: https://github.com/ruby/ruby/pull/12186
2024-11-13Move Array#map to RubyTakashi Kokubun
Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/12074
2024-09-13Prevent a warning: assigned but unused variable - exp_eventsYusuke Endoh
2024-08-16Fix assertion error when TracePoint has incompatible eventsPeter Zhu
TracePoints with incompatible events (i.e. events not in ISEQ_TRACE_EVENTS) with a method target will fail an assertion error because it does not filter for the supported events. For example, the following lines will cause an assertion error: def foo; end # No arguments passed into TracePoint.new enables all ISEQ_TRACE_EVENTS TracePoint.new {}.enable(target: method(:foo)) # Raise is not supported with a target TracePoint.new(:raise, :return) {}.enable(target: method(:foo)) foo Crashes with: Assertion Failed: vm_insnhelper.c:7026:vm_trace:(iseq_local_events & ~(0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010| 0x0020| 0x0040 | 0x0100 | 0x0200 | 0x4000 | 0x010000| 0x020000)) == 0 Notes: Merged: https://github.com/ruby/ruby/pull/11390
2024-08-16Fix flaky TestSetTraceFunc#test_remove_in_trace by filtering trace eventsNaoto Ono
Notes: Merged: https://github.com/ruby/ruby/pull/11368
2024-07-29Revert moving things to RubyAaron Patterson
This is slowing down benchmarks on x86, so lets revert it for now. Notes: Merged: https://github.com/ruby/ruby/pull/11275
2024-07-17Report a TracePoint log when the TracePoint tests failYusuke Endoh
Notes: Merged: https://github.com/ruby/ruby/pull/11184
2024-07-03Move Array#map to RubyAaron Patterson
Improves activerecord by about 1% on the interpreter: ``` before: ruby 3.4.0dev (2024-07-03T18:40:10Z master f88841b8f3) [arm64-darwin23] after: ruby 3.4.0dev (2024-07-03T18:41:14Z ruby-map 6c0df4eb32) [arm64-darwin23] ------------ ----------- ---------- ---------- ---------- ------------- ------------ bench before (ms) stddev (%) after (ms) stddev (%) after 1st itr before/after activerecord 235.2 0.8 233.6 0.7 1.01 1.01 ------------ ----------- ---------- ---------- ---------- ------------- ------------ Legend: - after 1st itr: ratio of before/after time for the first benchmarking iteration. - before/after: ratio of before/after time. Higher is better for after. Above 1 represents a speedup. ``` Improves YJIT by about 4%: ``` before: ruby 3.4.0dev (2024-07-03T18:40:10Z master f88841b8f3) +YJIT [arm64-darwin23] after: ruby 3.4.0dev (2024-07-03T18:41:14Z ruby-map 6c0df4eb32) +YJIT [arm64-darwin23] ------------ ----------- ---------- ---------- ---------- ------------- ------------ bench before (ms) stddev (%) after (ms) stddev (%) after 1st itr before/after activerecord 142.1 1.2 137.0 0.6 1.00 1.04 ------------ ----------- ---------- ---------- ---------- ------------- ------------ Legend: - after 1st itr: ratio of before/after time for the first benchmarking iteration. - before/after: ratio of before/after time. Higher is better for after. Above 1 represents a speedup. ```
2024-06-25Move to test/.excludes-prismNobuyoshi Nakada
2024-06-25Pending `EVENT_RETURN` settracefunc tests with PrismNobuyoshi Nakada
2024-06-25[Bug #20457] Do not remove final `return` nodeNobuyoshi Nakada
This was an optimization for versions prior to 1.9 that traverse the AST at runtime.
2024-03-04Disable callcc when ASAN is enabledKJ Tsanaktsidis
callcc's implementation is fundamentally incompatible with ASAN. Since callcc is deprecated and almost never used, it's probably OK to disable callcc when ruby is compiled with ASAN. [Bug #20273]
2024-02-22Ensure that exiting thread invokes end-of-life behaviour. (#10039)Samuel Williams
2024-02-15Do not include a backtick in error messages and backtracesYusuke Endoh
[Feature #16495]
2024-01-23Rewrite Array#each in Ruby using Primitive (#9533)Takashi Kokubun
2024-01-23Memory leak with TracePoint on bmethodPeter Zhu
[Bug #20194] When disabling the TracePoint on bmethod, the hooks list is not freed. For example: obj = Object.new obj.define_singleton_method(:foo) {} bmethod = obj.method(:foo) tp = TracePoint.new(:return) {} 10.times do 100_000.times do tp.enable(target: bmethod) {} end puts `ps -o rss= -p #{$$}` end Before: 18208 22832 26528 29728 34000 37776 40864 44400 47680 51504 After: 16688 17168 17168 17248 17696 17760 17824 17824 17856 17920
2023-12-12[Bug #19114] Fix for multiple calls of TracePoint#enableKouhei Yanagita
2023-12-07Support tracing of struct member accessor methodsJeremy Evans
This follows the same approach used for attr_reader/attr_writer in 2d98593bf54a37397c6e4886ccc7e3654c2eaf85, skipping the checking for tracing after the first call using the call cache, and clearing the call cache when tracing is turned on/off. Fixes [Bug #18886]
2023-11-15test: Follow-up fix for #8916Yuta Saito
`test_thread_trace` is also flaky due to the same reason as #8916. https://rubyci.s3.amazonaws.com/centos7/ruby-master/log/20231114T213002Z.fail.html.gz https://rubyci.s3.amazonaws.com/wsl2/ruby-master/log/20231114T090003Z.fail.html.gz
2023-11-14test: Assert only events originated from the test_settracefunc.rb test fileYuta Saito
This test suite is flaky on CI, because the test asserts events from finalizers also. Tracing events from finalizers is not deterministic and is not a part of test interests, so this commit changes the test to assert only events originated from the test file itself.
2023-11-14test: Check file name in test_thread_add_trace_func alsoYuta Saito
For better assert failure diagnostics.
2023-09-07Rewrite Integer#times in Ruby (#8388)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-08-09Prevent warnings: assigned but unused variableYusuke Endoh
2023-08-01support `rescue` event for TracePointKoichi Sasada
fix [Feature #19572] Notes: Merged: https://github.com/ruby/ruby/pull/8150
2023-08-01remove strange line eventKoichi Sasada
```ruby def helper_cant_rescue begin raise SyntaxError rescue cant_rescue # here end end ``` on this case, a line event is reported on `cant_rescue` line because of node structure. it should not be reported. Notes: Merged: https://github.com/ruby/ruby/pull/8149
2023-03-06s/MJIT/RJIT/Takashi Kokubun
Notes: Merged: https://github.com/ruby/ruby/pull/7462
2023-01-04Fix crash in TracePoint c_call for removed methodPeter Zhu
trace_arg->id is the ID of the original method of an aliased method. If the original method is removed, then the lookup will fail. We should use trace_arg->called_id instead, which is the ID of the aliased method. Fixes [Bug #19305] Notes: Merged: https://github.com/ruby/ruby/pull/7064
2022-12-25Rewrite Kernel#loop in Ruby (#6983)Takashi Kokubun
* Rewrite Kernel#loop in Ruby * Use enum_for(:loop) { Float::INFINITY } Co-authored-by: Ufuk Kayserilioglu <ufuk@paralaus.com> * Limit the scope to rescue StopIteration Co-authored-by: Ufuk Kayserilioglu <ufuk@paralaus.com> Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-12-21Make sure TracePoint#binding returns nil for c_call/c_return eventsJeremy Evans
This makes sure the method returns nil for these events, as described in NEWS, even if the TracePoint could create a binding. Notes: Merged: https://github.com/ruby/ruby/pull/6984 Merged-By: jeremyevans <code@jeremyevans.net>
2022-08-02Implement Queue#pop(timeout: sec)Jean Boussier
[Feature #18774] As well as `SizedQueue#pop(timeout: sec)` If both `non_block=true` and `timeout:` are supplied, ArgumentError is raised. Notes: Merged: https://github.com/ruby/ruby/pull/6185
2022-06-22Fix infinite loop when b_return TracePoint throwsAlan Wu
Previously, we didn't pop the frame that runs the TracePoint hook for b_return events for blocks running as methods (bmethods). In case the hook raises, that formed an infinite loop during stack unwinding in hook_before_rewind(). [Bug #18060] Notes: Merged: https://github.com/ruby/ruby/pull/4638
2022-06-10Fix nested bmethod TracePoint and memory leakAlan Wu
df317151a5b4e0c5a30fcc321a9dc6abad63f7ed removed the code to free rb_hook_list_t, so repeated targeting of the same bmethod started to leak the hook list. You can observe how the maximum memory use scales with input size in the following script with `/usr/bin/time -v`. ```ruby o = Object.new o.define_singleton_method(:foo) {} trace = TracePoint.new(:return) {} bmethod = o.method(:foo) ARGV.first.to_i.times { trace.enable(target:bmethod){} } 4.times {GC.start} ``` After this change the maximum doesn't grow as quickly. To plug the leak, check whether the hook list is already allocated when enabling the targeting TracePoint for the bmethod. This fix also allows multiple TracePoints to target the same bmethod, similar to other valid TracePoint targets. Finally, free the rb_hook_list_t struct when freeing the method definition it lives on. Freeing in the GC is a good way to avoid lifetime problems similar to the one fixed in df31715. [Bug #18031] Notes: Merged: https://github.com/ruby/ruby/pull/4651
2022-05-30Fix use-after-free with interacting TracePointsAlan Wu
`vm_trace_hook()` runs global hooks before running local hooks. Previously, we read the local hook list before running the global hooks which led to use-after-free when a global hook frees the local hook list. A global hook can do this by disabling a local TracePoint, for example. Delay local hook list loading until after running the global hooks. Issue discovered by Jeremy Evans in GH-5862. [Bug #18730] Notes: Merged: https://github.com/ruby/ruby/pull/5865
2022-04-06Raise RuntimeError if Kernel#binding is called from a non-Ruby frameJeremy Evans
Check whether the current or previous frame is a Ruby frame in call_trace_func and rb_tracearg_binding before attempting to create a binding for the frame. Fixes [Bug #18487] Co-authored-by: Alan Wu <XrXr@users.noreply.github.com> Notes: Merged: https://github.com/ruby/ruby/pull/5767 Merged-By: jeremyevans <code@jeremyevans.net>
2022-04-01Revert "Raise RuntimeError if Kernel#binding is called from a non-Ruby frame"Jeremy Evans
This reverts commit 343ea9967e4a6b279eed6bd8e81ad0bdc747f254. This causes an assertion failure with -DRUBY_DEBUG=1 -DRGENGC_CHECK_MODE=2
2022-03-29Avoid trace events in implementation of TracePoint#enableJeremy Evans
This is more backwards compatible, and should fix issues with power_assert. Unfortunately, it requires using a sentinel value as the default value of target_thread, instead of the more natural expression used in the original approach. Notes: Merged: https://github.com/ruby/ruby/pull/5359
2022-03-29Make TracePoint#enable with block target current thread by defaultJeremy Evans
If TracePoint#enable is passed a block, it previously started the trace on all threads. This changes it to trace only the current thread by default. To limit the scope of the change, the current thread is only used by default if target and target_line are both nil. You can pass target_thread: nil to enable tracing on all threads, to get the previous default behavior. Fixes [Bug #16889] Notes: Merged: https://github.com/ruby/ruby/pull/5359
2022-03-24Raise RuntimeError if Kernel#binding is called from a non-Ruby frameJeremy Evans
Check whether the current or previous frame is a Ruby frame in call_trace_func before attempting to create a binding for the frame. Fixes [Bug #18487] Co-authored-by: Alan Wu <XrXr@users.noreply.github.com> Notes: Merged: https://github.com/ruby/ruby/pull/5567
2022-01-14Add a Module#const_added callbackJean Boussier
[Feature #17881] Works similarly to `method_added` but for constants. ```ruby Foo::BAR = 42 # call Foo.const_added(:FOO) class Foo::Baz; end # call Foo.const_added(:Baz) Foo.autoload(:Something, "path") # call Foo.const_added(:Something) ``` Notes: Merged: https://github.com/ruby/ruby/pull/4521
2022-01-04Use omit instead of skip: test/ruby/**/*.rbHiroshi SHIBATA