| Age | Commit message (Collapse) | Author |
|
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
|
|
Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org>
Notes:
Merged: https://github.com/ruby/ruby/pull/12074
|
|
|
|
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
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/11368
|
|
This is slowing down benchmarks on x86, so lets revert it for now.
Notes:
Merged: https://github.com/ruby/ruby/pull/11275
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/11184
|
|
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.
```
|
|
|
|
|
|
This was an optimization for versions prior to 1.9 that traverse the
AST at runtime.
|
|
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]
|
|
|
|
[Feature #16495]
|
|
|
|
[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
|
|
|
|
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]
|
|
`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
|
|
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.
|
|
For better assert failure diagnostics.
|
|
Notes:
Merged-By: k0kubun <takashikkbn@gmail.com>
|
|
|
|
fix [Feature #19572]
Notes:
Merged: https://github.com/ruby/ruby/pull/8150
|
|
```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
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/7462
|
|
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
|
|
* 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>
|
|
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>
|
|
[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
|
|
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
|
|
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
|
|
`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
|
|
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>
|
|
This reverts commit 343ea9967e4a6b279eed6bd8e81ad0bdc747f254.
This causes an assertion failure with -DRUBY_DEBUG=1 -DRGENGC_CHECK_MODE=2
|
|
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
|
|
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
|
|
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
|
|
[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
|
|
|
|
Notes:
Merged-By: k0kubun <takashikkbn@gmail.com>
|
|
In general, while TracePoint callback is running,
other registerred callbacks are not called to avoid
confusion by reentrace.
This method allow the reentrace. This method should be
used carefully, otherwize the callback can be easily called
infinitely.
[Feature #15912]
Co-authored-by: Jean Boussier <jean.boussier@gmail.com>
Notes:
Merged: https://github.com/ruby/ruby/pull/5231
|
|
The main impetus for this change is to fix [Bug #13392]. Previously, we
fired the "return" TracePoint event after popping the stack frame for
the block running as method (BMETHOD). This gave undesirable source
location outputs as the return event normally fires right before the
frame going away.
The iseq for each block can run both as a block and as a method. To
accommodate that, this commit makes vm_trace() fire call/return events for
instructions that have b_call/b_return events attached when the iseq is
running as a BMETHOD. The logic for rewriting to "trace_*" instruction
is tweaked so that when the user listens to call/return events,
instructions with b_call/b_return become trace variants.
To continue to provide the return value for non-local returns done using
the "return" or "break" keyword inside BMETHODs, the stack unwinding
code is tweaked. b_return events now provide the same return value as
return events for these non-local cases. A pre-existing test deemed not
providing a return value for these b_return events as a limitation.
This commit removes the checks for call/return TracePoint events that
happen when calling into BMETHODs when no TracePoints are active.
Technically, migrating just the return event is enough to fix the bug,
but migrating both call and return removes our reliance on
`VM_FRAME_FLAG_FINISH` and re-entering the interpreter when the caller
is already in the interpreter.
Notes:
Merged: https://github.com/ruby/ruby/pull/4637
|
|
Notes:
Merged: https://github.com/ruby/ruby/pull/5102
|
|
TracePoint leaks memory because it allocates a `rb_tp_t` struct
without ever freeing it (it is created with `RUBY_TYPED_NEVER_FREE`).
Notes:
Merged: https://github.com/ruby/ruby/pull/5008
|
|
In vm_call_method_each_type, check for c_call and c_return events before
dispatching to vm_call_ivar and vm_call_attrset. With this approach, the
call cache will still dispatch directly to those functions, so this
change will only decrease performance for the first (uncached) call, and
even then, the performance decrease is very minimal.
This approach requires that we clear the call caches when tracing is
enabled or disabled. The approach currently switches all vm_call_ivar
and vm_call_attrset call caches to vm_call_general any time tracing is
enabled or disabled. So it could theoretically result in a slowdown for
code that constantly enables or disables tracing.
This approach does not handle targeted tracepoints, but from my testing,
c_call and c_return events are not supported for targeted tracepoints,
so that shouldn't matter.
This includes a benchmark showing the performance decrease is minimal
if detectable at all.
Fixes [Bug #16383]
Fixes [Bug #10470]
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
Notes:
Merged: https://github.com/ruby/ruby/pull/4767
|
|
`TracePoint.stat` returns the "to be deleted" TP numbers, and
http://rubyci.s3.amazonaws.com/graviton2/ruby-master/log/20210810T030003Z.fail.html.gz
shows there is a "to be deleted" TP.
This patch uses only :line event and add some lines to allow MRI
deletes "to be deleted" TPs.
|
|
|
|
Fixes [Bug #17868]
|
|
With this patch, TracePoint receives a `:fiber_switch` event for
_almost_ every fiber switch. Previously, it would not be sent when an
exception was going to be raised. Now the event should only be blockable
by an interrupt (including `Thread#raise`) or a fatal error.
Additionally, interrupts will now be checked on the return fiber
_before_ re-raising the terminating unhandled exception. And a fiber
that terminates with an unhandled exception no longer creates a pending
interrupt on its thread. The exception will be raised in the return
fiber the same way as `Fiber#raise`: using `cont.value` with `cont.argc
== -1`
I moved `rb_exc_raise` from `fiber_store` to the end of `fiber_switch`
after _all_ of the other cleanup code: `fiber_stack_release`,
`th->blocking` increment, `RUBY_VM_CHECK_INTS`, and `EXEC_EVENT_HOOK`.
It seems to me that skipping those other cleanup steps may have also
resulted in other bugs.
Notes:
Merged-By: ioquatix <samuel@codeotaku.com>
|