[#118415] [Ruby master Bug#20601] Configuration flags are not properly propagated to assembler — "vo.x (Vit Ondruch) via ruby-core" <ruby-core@...>

Issue #20601 has been reported by vo.x (Vit Ondruch).

7 messages 2024/07/02

[#118467] [Ruby master Feature#20610] Float::INFINITY as IO.select timeout argument — "akr (Akira Tanaka) via ruby-core" <ruby-core@...>

Issue #20610 has been reported by akr (Akira Tanaka).

8 messages 2024/07/07

[#118483] [Ruby master Bug#20614] Integer#size returns incorrect values on 64-bit Windows — surusek via ruby-core <ruby-core@...>

SXNzdWUgIzIwNjE0IGhhcyBiZWVuIHJlcG9ydGVkIGJ5IHN1cnVzZWsgKMWBdWthc3ogU3VyKS4N

10 messages 2024/07/08

[#118577] [Ruby master Bug#20631] Build failure with Xcode 16 beta and macOS 15 (Sequoia) Beta — "hsbt (Hiroshi SHIBATA) via ruby-core" <ruby-core@...>

Issue #20631 has been reported by hsbt (Hiroshi SHIBATA).

9 messages 2024/07/12

[#118682] [Ruby master Misc#20652] Memory allocation for gsub has increased from Ruby 2.7 to 3.3 — "orisano (Nao Yonashiro) via ruby-core" <ruby-core@...>

Issue #20652 has been reported by orisano (Nao Yonashiro).

28 messages 2024/07/25

[ruby-core:118460] [Ruby master Bug#20286] TracePoint does not emit `thread_end` event when thread exits with exception

From: "nagachika (Tomoyuki Chikanaga) via ruby-core" <ruby-core@...>
Date: 2024-07-06 06:35:11 UTC
List: ruby-core #118460
Issue #20286 has been updated by nagachika (Tomoyuki Chikanaga).

Backport changed from 3.0: REQUIRED, 3.1: REQUIRED, 3.2: REQUIRED, 3.3: DONE to 3.0: REQUIRED, 3.1: REQUIRED, 3.2: DONE, 3.3: DONE

ruby_3_2 commit:89de66dbb0d8454c9d69faa331d6e35f8b315cce merged revision(s) commit:78d9fe69479d32214a52ad7291c3973f1b6b7f6f, commit:04729fe68dceddab045be7324e26c2bb15aa62c7.

----------------------------------------
Bug #20286: TracePoint does not emit `thread_end` event when thread exits with exception
https://bugs.ruby-lang.org/issues/20286#change-108974

* Author: ioquatix (Samuel Williams)
* Status: Closed
* Assignee: ioquatix (Samuel Williams)
* Backport: 3.0: REQUIRED, 3.1: REQUIRED, 3.2: DONE, 3.3: DONE
----------------------------------------
Using TracePoint to trace `thread_begin` and `thread_end` events fails to emit the `thread_end` event when an exception (e.g., Interrupt) is raised within a thread. This behavior occurs because the exception handling bypasses the internal thread finishing logic, including trace point and fiber scheduler cleanup code. This issue affects the ability to accurately monitor thread lifecycle events in scenarios involving exception handling or abrupt thread terminations.

## Steps to Reproduce:

1. Set up `TracePoint` to trace `thread_begin` and `thread_end` events.
2. Create a new thread that raises an exception.
3. Join the thread and observe that only the `thread_begin` event is emitted without a corresponding `thread_end` event.

## Example Code

```ruby
TracePoint.trace(:thread_begin, :thread_end) do |tp|
  p [tp.event, tp.lineno, tp.path, tp.defined_class, tp.method_id]
end

thread = Thread.new do
  raise Interrupt
end

thread.join
```

### Current Behavior:

The `TracePoint` emits the `thread_begin` event but fails to emit the `thread_end` event when an exception is raised within the thread, indicating an incomplete tracing of thread lifecycle events.

I've confirmed this as far back as Ruby 2.6.

```
> ruby ./test.rb
[:thread_begin, 0, nil, nil, nil]
#<Thread:0x000000010384b5a8 ./test.rb:5 run> terminated with exception (report_on_exception is true):
./test.rb:6:in `block in <main>': Interrupt (Interrupt)
./test.rb:6:in `block in <main>': Interrupt (Interrupt)
```

### Expected Behavior:

The `TracePoint` should emit both `thread_begin` and `thread_end` events, accurately reflecting the lifecycle of the thread, even when an exception is raised within the thread.

```
> ruby ./test.rb
[:thread_begin, 0, nil, nil, nil]
[:thread_end, 0, nil, nil, nil]
#<Thread:0x0000000105435db8 ./test.rb:5 run> terminated with exception (report_on_exception is true):
./test.rb:6:in 'block in <main>': Interrupt (Interrupt)
./test.rb:6:in 'block in <main>': Interrupt (Interrupt)
```

## Possible Fix

Changing the implementation of `thread_do_start` to have what amounts to an "ensure" block.

```c
static void
thread_do_start(rb_thread_t *th)
{
    native_set_thread_name(th);
    VALUE result = Qundef;

    rb_execution_context_t *ec = th->ec;
    int state;

    EXEC_EVENT_HOOK(ec, RUBY_EVENT_THREAD_BEGIN, th->self, 0, 0, 0, Qundef);

    EC_PUSH_TAG(ec);
    if ((state = EC_EXEC_TAG()) == TAG_NONE) {
        switch (th->invoke_type) {
        case thread_invoke_type_proc:
            result = thread_do_start_proc(th);
            break;

        case thread_invoke_type_ractor_proc:
            result = thread_do_start_proc(th);
            rb_ractor_atexit(th->ec, result);
            break;

        case thread_invoke_type_func:
            result = (*th->invoke_arg.func.func)(th->invoke_arg.func.arg);
            break;

        case thread_invoke_type_none:
            rb_bug("unreachable");
        }
    }

    EC_POP_TAG();
    VALUE errinfo = ec->errinfo;

    if (!NIL_P(errinfo) && !RB_TYPE_P(errinfo, T_OBJECT)) {
        ec->errinfo = Qnil;
    }

    rb_fiber_scheduler_set(Qnil);
    EXEC_EVENT_HOOK(th->ec, RUBY_EVENT_THREAD_END, th->self, 0, 0, 0, Qundef);

    ec->errinfo = errinfo;

    if (state)
        EC_JUMP_TAG(ec, state);

    th->value = result;
}
```

It's possible `rb_fiber_scheduler_set(Qnil);` can emit an exception itself. How do we write the code to handle that case?



-- 
https://bugs.ruby-lang.org/
 ______________________________________________
 ruby-core mailing list -- ruby-core@ml.ruby-lang.org
 To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
 ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/


In This Thread

Prev Next