272 Commits
Author SHA1 Message Date
Luke Gruber 4fb537b1ee Make tracepoints with set_trace_func or TracePoint.new ractor local (#15468)
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-12-16 14:06:55 -05:00
John Hawthorn de94f88c68 Register internal tracepoints globally
Internal tracepoints only make sense to run globally, and they already
took completely different paths.
2025-12-08 16:38:45 -08:00
John Hawthorn 55668d7484 Only globally clear the flag being cleared
This solution is not quite correct because it doesn't solve multiple
Ractors subscribing to the same event, but this will avoid unrelated
events clobbering the flags for other events.

This however will work corretly for subscribing to global ObjectSpace GC
events.
2025-12-08 16:38:45 -08:00
Koichi Sasada 860bad854f specific traces can be unshareable 2025-10-30 18:04:08 +09:00
Stan Lo 77a421fb05 ZJIT: Clear jit entry from iseqs after TracePoint activation (#14407)
ZJIT: Remove JITed code after TracePoint is enabled
2025-09-02 19:20:08 +00:00
Peter Zhu 6c0315d99a Rename rb_hook_list_mark_and_update to rb_hook_list_mark_and_move 2025-08-27 10:34:40 -04:00
刘皓 45e814d116 Fix jump buffer leak in WASI builds 2025-04-27 15:47:30 +09:00
Nobuyoshi Nakada 4a67ef09cc [Feature #21116] Extract RJIT as a third-party gem 2025-02-13 18:01:03 +09:00
viralpraxis 660b995365 [Bug #20915] Fix SEGV with TracePoint#parameters and aliased C method
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`.
2024-11-29 18:42:48 -05:00
Nobuyoshi Nakada 9a90cd2284 Cast via uintptr_t function pointer between object pointer
- ISO C forbids conversion of function pointer to object pointer type
- ISO C forbids conversion of object pointer to function pointer type
2024-10-08 23:29:49 +09:00
Peter Zhu 2fe6a4f84d Fix assertion error when TracePoint has incompatible events
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
2024-08-16 16:12:49 -04:00
Nobuyoshi Nakada 28a2105a55 Prefer enum ruby_tag_type over int 2024-03-17 15:57:19 +09:00
Jean Boussier b4a69351ec Move FL_SINGLETON to FL_USER1
This frees FL_USER0 on both T_MODULE and T_CLASS.

Note: prior to this, FL_SINGLETON was never set on T_MODULE,
so checking for `FL_SINGLETON` without first checking that
`FL_TYPE` was `T_CLASS` was valid. That's no longer the case.
2024-03-06 13:11:41 -05:00
Yusuke Endoh 25d74b9527 Do not include a backtick in error messages and backtraces
[Feature #16495]
2024-02-15 18:42:31 +09:00
Peter Zhu b14674b236 Memory leak with TracePoint on bmethod
[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
2024-01-23 10:47:04 -05:00
Takashi Kokubun 8642a573e6 Rename BUILTIN_ATTR_SINGLE_NOARG_INLINE
to BUILTIN_ATTR_SINGLE_NOARG_LEAF

The attribute was created when the other attribute was called BUILTIN_ATTR_INLINE.
Now that the original attribute is renamed to BUILTIN_ATTR_LEAF, it's
only confusing that we call it "_INLINE".
2024-01-16 17:31:27 -08:00
Nobuyoshi Nakada c30b8ae947 Adjust styles and indents [ci skip] 2024-01-08 00:50:41 +09:00
John Hawthorn 697a096c9b Remove EC argument from clean_hooks_check
This argument doesn't seem used anymore. Since we want to free these
objects during VM destruction when RUBY_FREE_AT_EXIT is set they must
work without an EC.

This avoids a use-after-free running `RUBY_FREE_AT_EXIT=1 ./miniruby -e ''`
2023-12-22 18:07:22 -08:00
KJ Tsanaktsidis 4eefab592a Refactor local variable names in postponed_job methods
Just removes the unneeded `prereg_` prefix from a few local var names.
2023-12-13 13:35:05 +11:00
Kouhei Yanagita 06e2fbb826 [Bug #19114] Fix for multiple calls of TracePoint#enable 2023-12-12 09:36:37 -08:00
Koichi Sasada c4c39082af add flags to rb_postponed_job_preregister
for future extensions.
2023-12-10 15:39:06 +09:00
KJ Tsanaktsidis f8effa209a Change the semantics of rb_postponed_job_register
Our current implementation of rb_postponed_job_register suffers from
some safety issues that can lead to interpreter crashes (see bug #1991).
Essentially, the issue is that jobs can be called with the wrong
arguments.

We made two attempts to fix this whilst keeping the promised semantics,
but:
  * The first one involved masking/unmasking when flushing jobs, which
    was believed to be too expensive
  * The second one involved a lock-free, multi-producer, single-consumer
    ringbuffer, which was too complex

The critical insight behind this third solution is that essentially the
only user of these APIs are a) internal, or b) profiling gems.

For a), none of the usages actually require variable data; they will
work just fine with the preregistration interface.

For b), generally profiling gems only call a single callback with a
single piece of data (which is actually usually just zero) for the life
of the program. The ringbuffer is complex because it needs to support
multi-word inserts of job & data (which can't be atomic); but nobody
actually even needs that functionality, really.

So, this comit:
  * Introduces a pre-registration API for jobs, with a GVL-requiring
    rb_postponed_job_prereigster, which returns a handle which can be
    used with an async-signal-safe rb_postponed_job_trigger.
  * Deprecates rb_postponed_job_register (and re-implements it on top of
    the preregister function for compatability)
  * Moves all the internal usages of postponed job register
    pre-registration
2023-12-10 15:00:37 +09:00
Peter Zhu 5672fb63d2 Implement TracePoint on VWA 2023-11-22 16:01:00 -05:00
Peter Zhu 0f24ecf17a Implement Write Barriers on TracePoint 2023-11-22 08:38:36 -05:00
Nobuyoshi Nakada 2ac3e9abe9 [Bug #18487] [DOC] Remove stale note in set_trace_func document
`c-call` and `c-return events no longer pass the nearest Ruby method
binding.
2023-09-04 10:35:26 +09:00
Nobuyoshi Nakada ba8a7ab8a8 [DOC] Update set_trace_func document
- Clarify the class of event parameters
- Represent event names as strings
- Update the example to show the above
2023-09-04 10:35:26 +09:00
Nobuyoshi Nakada 3b7c8e90da [DOC] Fix indent of set_trace_func document 2023-09-04 10:35:26 +09:00
Koichi Sasada d68c01fd31 support rescue event for TracePoint
fix [Feature #19572]
2023-08-01 22:46:17 +09:00
Nobuyoshi Nakada 8d242a33af rb_bug prints a newline after the message 2023-05-20 21:43:30 +09:00
Koichi Sasada c9fd81b860 vm_call_single_noarg_inline_builtin
If the iseq only contains `opt_invokebuiltin_delegate_leave` insn and
the builtin-function (bf) is inline-able, the caller doesn't need to
build a method frame.

`vm_call_single_noarg_inline_builtin` is fast path for such cases.
2023-03-23 14:03:12 +09:00
Takashi Kokubun 23ec248e48 s/mjit/rjit/ 2023-03-06 23:44:01 -08:00
Takashi Kokubun 233ddfac54 Stop exporting symbols for MJIT 2023-03-06 21:59:23 -08:00
Jean Boussier 7413079dae Encapsulate RCLASS_ATTACHED_OBJECT
Right now the attached object is stored as an instance variable
and all the call sites that either get or set it have to know how it's
stored.

It's preferable to hide this implementation detail behind accessors
so that it is easier to change how it's stored.
2023-02-15 15:24:22 +01:00
Peter Zhu 056e7a0154 Make all of the references of iseq movable 2023-01-20 08:51:39 -05:00
Peter Zhu 837ef8911c Fix crash in TracePoint c_call for removed method
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]
2023-01-04 14:59:40 -05:00
Takashi Kokubun b9332ac8e7 MJIT: Cancel all on disastrous situations (#7019)
I noticed this while running test_yjit with --mjit-call-threshold=1, 
which redefines `Integer#<`. When Ruby is monkey-patched, 
MJIT itself could be broken.

Similarly, Ruby scripts could break MJIT in many different ways. I
prepared the same set of hooks as YJIT so that we could possibly
override it and disable it on those moments. Every constant under
RubyVM::MJIT is private and thus it's an unsupported behavior though.
2022-12-24 01:13:40 -08:00
Jeremy Evans 4213f42555 Make sure TracePoint#binding returns nil for c_call/c_return events
This makes sure the method returns nil for these events, as
described in NEWS, even if the TracePoint could create a binding.
2022-12-21 21:02:43 -08:00
S-H-GAMELINKS 1f4f6c9832 Using UNDEF_P macro 2022-11-16 18:58:33 +09:00
Takashi Kokubun dc5e2eaab6 Refactor update_global_event_hook
It seems more readable to put JIT invalidation code together.
2022-11-13 15:13:44 -08:00
Alan Wu bc8ba244b8 YJIT: Fix invalidation for c_call and c_return (#6719)
Follow-up for 2b8191bdad. Since that
commit, we stopped doing code invalidation the second time the call and
return events are enabled. We need to do it every time these events are
enabled because we might have generated code while these events are
disabled.

Also rename locals and edit comments to make it more clear that the iseq
rewrite code path only happens the first time a particular iseq trace
event is enabled.
2022-11-13 12:51:19 -05:00
Takashi Kokubun 2b8191bdad YJIT: Invalidate JIT code only for ISEQ_TRACE_EVENTS (#6695) 2022-11-10 17:12:38 -05:00
Takashi Kokubun 5b21e94beb Expand tabs [ci skip]
[Misc #18891]
2022-07-21 09:42:04 -07:00
Alan Wu 744d17ff6c Fix infinite loop when b_return TracePoint throws
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]
2022-06-22 08:30:39 -04:00
Alan Wu e75cb61d46 Fix nested bmethod TracePoint and memory leak
df317151a5 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]
2022-06-10 10:10:27 +09:00
Jeremy EvansandAlan Wu 0b091fdac6 Raise RuntimeError if Kernel#binding is called from a non-Ruby frame
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>
2022-04-06 19:14:03 -07:00
Jeremy Evans d1d48cb690 Revert "Raise RuntimeError if Kernel#binding is called from a non-Ruby frame"
This reverts commit 343ea9967e.

This causes an assertion failure with -DRUBY_DEBUG=1 -DRGENGC_CHECK_MODE=2
2022-04-01 07:22:49 -07:00
Nobuyoshi NakadaandSamuel Williams 42a0bed351 Prefix ccan headers (#4568)
* Prefixed ccan headers

* Remove unprefixed names in ccan/build_assert

* Remove unprefixed names in ccan/check_type

* Remove unprefixed names in ccan/container_of

* Remove unprefixed names in ccan/list

Co-authored-by: Samuel Williams <samuel.williams@oriontransfer.co.nz>
2022-03-30 20:36:31 +13:00
Jeremy Evans 3c6a0033e3 Avoid trace events in implementation of TracePoint#enable
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.
2022-03-29 18:14:33 -07:00
Jeremy EvansandAlan Wu 343ea9967e Raise RuntimeError if Kernel#binding is called from a non-Ruby frame
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>
2022-03-24 12:31:07 -07:00
Kazuhiro NISHIYAMA c00e360bc0 Fix error: old-style function definition
https://rubyci.s3.amazonaws.com/debian-riscv64/ruby-master/log/20220122T050018Z.log.html.gz#miniruby
```
compiling vm_trace.c
vm_trace.c: In function 'rb_vm_memsize_postponed_job_buffer':
vm_trace.c:1599:1: error: old-style function definition [-Werror=old-style-definition]
 1599 | rb_vm_memsize_postponed_job_buffer()
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
2022-01-22 15:48:05 +09:00