Skip to content

Don't inspect hidden classes when printing captured calls - #9

Closed
trevorturk wants to merge 1 commit into
socketry:mainfrom
trevorturk:fix-hidden-class-inspect
Closed

trevorturk wants to merge 1 commit into
socketry:mainfrom
trevorturk:fix-hidden-class-inspect

Conversation

@trevorturk

Copy link
Copy Markdown

Fixes #7.

Problem

In capture mode, printing a stall can raise NotImplementedError: method 'inspect' called on hidden T_CLASS object from the fiber-switch hook. The exception escapes into whatever resumed the fiber (the scheduler's select under Async/Falcon), which kills the worker.

Cause

CRuby defines its internal helpers for ->{}, ** hash merges, alias and similar on the singleton class of RubyVM::FrozenCore, and hides that class (RBASIC_CLEAR_CLASS in Init_VM). CRuby skips regular trace events for FrozenCore, but not internal GC events. When a GC starts during one of these helpers, rb_frame_method_id_and_class in the GC_START hook returns the hidden class, and rb_inspect on it raises.

Fix

When the class is hidden, both the TTY and JSON printers use rb_class_path instead of rb_inspect, which doesn't dispatch a method on the class. Such calls now print as e.g. #<Class:0x…>#lambda.

Testing

When a GC starts inside a method defined on a hidden class, such as the
singleton class of `RubyVM::FrozenCore` (which implements `->{}`, `**`
hash merges and similar), `rb_frame_method_id_and_class` returns that
hidden class as the owner of the GC call. Printing the report then
called `rb_inspect` on it, which raises `NotImplementedError` out of the
fiber switch hook and into whatever resumed the fiber.

Use `rb_class_path` for hidden classes instead, which doesn't dispatch
a method on the class.

Fixes socketry#7.
@trevorturk

Copy link
Copy Markdown
Author

Closing in favor of #8. I left validation results, a suggested tweak and tests there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Capture mode: rb_inspect on a hidden T_CLASS raises out of the fiber-switch hook and kills the worker

1 participant