1- name : Test Ruby GC Bug
2-
3- # Builds unfixed Ruby (no rb_gc_register_address in scheduler.c) and tests
4- # whether the worker_pool.c fix alone is sufficient to prevent the crash.
1+ name : Test Ruby GC Bug — Disassembly Comparison
52
63on : [push, pull_request]
74
85jobs :
9- test :
10- name : io-event (worker_pool fix) vs unfixed Ruby
6+ disassembly :
7+ name : Compare disassembly (CASE_A vs CASE_B)
118 runs-on : ubuntu-24.04
129
1310 steps :
@@ -18,16 +15,16 @@ jobs:
1815 sudo apt-get update -q
1916 sudo apt-get install -y --no-install-recommends \
2017 ruby bison libyaml-dev libgdbm-dev libreadline-dev libncurses5-dev \
21- liburing-dev autoconf automake gcc make
18+ liburing-dev autoconf automake gcc make binutils
2219
23- - name : Clone Ruby (unfixed master @ bug/blocking-operation-gc)
20+ - name : Clone Ruby (bug/blocking-operation-gc)
2421 uses : actions/checkout@v4
2522 with :
2623 repository : samuel-williams-shopify/ruby
2724 ref : bug/blocking-operation-gc
2825 path : ruby-src
2926
30- - name : Build Ruby (same flags as ruby-dev-builder head )
27+ - name : Configure Ruby (once — same flags for both cases )
3128 working-directory : ruby-src
3229 run : |
3330 ./autogen.sh
@@ -37,21 +34,53 @@ jobs:
3734 --disable-install-doc \
3835 --enable-yjit \
3936 cppflags="-DENABLE_PATH_CHECK=0"
40- make -j$(nproc)
41- make install
42- echo "$HOME/.rubies/ruby-head/bin" >> $GITHUB_PATH
4337
44- - name : Show Ruby version
45- run : ruby --version
38+ - name : Build CASE_B — operation = get_blocking_operation (works)
39+ working-directory : ruby-src
40+ run : make -j$(nproc)
4641
47- - name : Install bundler and gems
42+ - name : Disassemble CASE_B
43+ working-directory : ruby-src
4844 run : |
49- gem install bundler --no-document
50- bundle install
45+ objdump -d --no-show-raw-insn -M intel libruby.so \
46+ | awk '/^[0-9a-f]+ <rb_fiber_scheduler_blocking_operation_wait>:/{found=1} found{print} found && /^$/{exit}' \
47+ > /tmp/case_b.asm
48+ echo "CASE_B lines: $(wc -l < /tmp/case_b.asm)"
5149
52- - name : Build io-event native extension
53- run : bundle exec bake build
50+ - name : Patch to CASE_A — operation = NULL (fails)
51+ working-directory : ruby-src
52+ run : |
53+ sed -i 's/rb_fiber_scheduler_blocking_operation_t \*operation = get_blocking_operation(blocking_operation);/rb_fiber_scheduler_blocking_operation_t *operation = NULL;/' scheduler.c
54+ grep -n "operation = NULL\|operation = get_blocking" scheduler.c
55+
56+ - name : Build CASE_A
57+ working-directory : ruby-src
58+ run : make -j$(nproc)
5459
55- - name : Run tests
56- timeout-minutes : 10
57- run : bundle exec bake test
60+ - name : Disassemble CASE_A
61+ working-directory : ruby-src
62+ run : |
63+ objdump -d --no-show-raw-insn -M intel libruby.so \
64+ | awk '/^[0-9a-f]+ <rb_fiber_scheduler_blocking_operation_wait>:/{found=1} found{print} found && /^$/{exit}' \
65+ > /tmp/case_a.asm
66+ echo "CASE_A lines: $(wc -l < /tmp/case_a.asm)"
67+
68+ - name : Print diff
69+ run : |
70+ echo "=== CASE_A (operation=NULL, FAILS) ==="
71+ cat /tmp/case_a.asm
72+ echo ""
73+ echo "=== CASE_B (operation=get_blocking_operation, WORKS) ==="
74+ cat /tmp/case_b.asm
75+ echo ""
76+ echo "=== DIFF (A vs B) ==="
77+ diff /tmp/case_a.asm /tmp/case_b.asm || true
78+
79+ - name : Upload disassembly artifacts
80+ uses : actions/upload-artifact@v4
81+ if : always()
82+ with :
83+ name : disassembly
84+ path : |
85+ /tmp/case_a.asm
86+ /tmp/case_b.asm
0 commit comments