Skip to content

Use newer APIs for ruby head/4.1 support - #109

Merged
SamSaffron merged 5 commits into
tmm1:masterfrom
rwstauner:deprecated
Aug 6, 2026
Merged

Use newer APIs for ruby head/4.1 support#109
SamSaffron merged 5 commits into
tmm1:masterfrom
rwstauner:deprecated

Conversation

@rwstauner

@rwstauner rwstauner commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

The deprecated ones have been removed from ruby as of 2026-04-12
ruby/ruby@b66b500

This resolves a compilation error with ruby head:

rbtrace.c:1160:37: error: incompatible function pointer types passing 'VALUE (VALUE, VALUE)' (aka 'unsigned long (unsigned long, unsigned long)') to parameter of
      type 'rb_block_call_func_t' (aka 'unsigned long (*)(unsigned long, unsigned long, int, const unsigned long *, unsigned long)') [-Wincompatible-function-pointer-types]
 1160 |   signal_handler_proc = rb_proc_new(signal_handler_wrapper, Qnil);
      |                                     ^~~~~~~~~~~~~~~~~~~~~~

@rwstauner
rwstauner marked this pull request as ready for review June 3, 2026 00:26
@rwstauner rwstauner changed the title Use newer postponed_job APIs if present Use newer postponed_job APIs if present for ruby head/4.1 support Aug 5, 2026
Comment thread ext/rbtrace.c
@rwstauner

Copy link
Copy Markdown
Contributor Author

@SamSaffron I would appreciate a review if you have time to look at this fix for newer ruby versions. Thanks!

@SamSaffron

Copy link
Copy Markdown
Collaborator

I follow, the challenge I have here is that I am not mega familiar with all the new APIs so I am stuck trusting my robot testing skills :)

feedback from robot analysis:

  • rbtrace -h is failing, not your fault, but we should clean up. Do you mind fixing? (missing a require 'objspace') - also oddly we are missing a test for this

  • looks like 4.1 are removing ObjectSpace._id2ref which we lean on, we should clean that up. Perhaps something along the lines of:

diff --git a/ext/rbtrace.c b/ext/rbtrace.c
index 9bc259a..1e5c6c8 100644
--- a/ext/rbtrace.c
+++ b/ext/rbtrace.c
@@ -491,8 +491,9 @@ event_hook(rb_event_t event, NODE *node, VALUE self, ID mid, VALUE klass)
             val = rb_inspect(rb_ivar_get(self, rb_intern(expr)));
 
           } else {
-            snprintf(buffer, len+150, "(begin; ObjectSpace._id2ref(%ld).instance_eval{ %s }; rescue Exception => e; e; end).inspect", NUM2LONG(rb_obj_id(self)), expr);
-            val = rb_eval_string_protect(buffer, 0);
+            snprintf(buffer, len+150, "proc { |__rbtrace_receiver__| (begin; __rbtrace_receiver__.instance_eval { %s }; rescue Exception => e; e; end).inspect }", expr);
+            VALUE expr_proc = rb_eval_string_protect(buffer, 0);
+            val = rb_funcall(expr_proc, rb_intern("call"), 1, self);
           }
 
           if (RTEST(val) && TYPE(val) == T_STRING) {
diff --git a/server.rb b/server.rb
index 20b5314..05806fc 100644
--- a/server.rb
+++ b/server.rb
@@ -32,6 +32,7 @@ while true
         Dir.pwd
         Process.pid
         'hello'.multiply_vowels(3){ :ohai }
+        'hello'.upcase
         sleep rand*0.5
 
         ENV['blah']
diff --git a/test.sh b/test.sh
index bd735d7..ccedf51 100755
--- a/test.sh
+++ b/test.sh
@@ -51,11 +51,34 @@ assert_trace() {
   echo
 }
 
+assert_timed_trace() {
+  expected="$1"
+  shift
+  output=$(mktemp)
+
+  echo ------------------------------------------
+  echo ./bin/rbtrace -p $PID "$@"
+  echo ------------------------------------------
+  bundle exec ./bin/rbtrace -p $PID "$@" >"$output" 2>&1 &
+  tracer_pid=$!
+  sleep 2
+  kill "$tracer_pid" 2>/dev/null || true
+  wait "$tracer_pid" 2>/dev/null || true
+  cat "$output"
+  if ! grep -F "$expected" "$output" >/dev/null; then
+    rm -f "$output"
+    return 1
+  fi
+  rm -f "$output"
+  echo
+}
+
 trace -m Test.run --devmode
 trace -m sleep
 trace -m sleep Dir.chdir Dir.pwd Process.pid "String#gsub" "String#*"
 trace -m "Kernel#"
 trace -m "String#gsub(self,@test)" "String#*(self,__source__)" "String#multiply_vowels(self,self.length,num)"
+assert_timed_trace 'String#upcase(self.class=String)' -m 'String#upcase(self.class)'
 assert_trace '=> 2' -e 'p(1 + 1)'
 trace -h
 trace --gc --slow=200
  • CI is not testing on head, do you mind adding to the CI checks so we keep it honest

@rwstauner

Copy link
Copy Markdown
Contributor Author

Awesome, thank you @SamSaffron!

  • added tests for --heapdump and --shapesdump to ensure objspace is loaded.
  • used your proc replacement idea for id2ref
  • added head to CI

@rwstauner rwstauner changed the title Use newer postponed_job APIs if present for ruby head/4.1 support Use newer APIs for ruby head/4.1 support Aug 6, 2026
@SamSaffron

Copy link
Copy Markdown
Collaborator

Looks good ... will cut a new version!

@SamSaffron
SamSaffron merged commit 034c14c into tmm1:master Aug 6, 2026
@rwstauner

Copy link
Copy Markdown
Contributor Author

Thank you!

@SamSaffron

Copy link
Copy Markdown
Collaborator

Thanks Randy, if there are any other changes you feel we need happy to add them in.

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.

3 participants