Bug #13298


mingw SEGV TestEnumerable#test_callcc

Added by MSP-Greg (Greg L) almost 6 years ago. Updated about 1 month ago.

Target version:
ruby -v:
ruby 2.5.0dev (2017-03-09 trunk 57821) [x64-mingw32]


First week in January, when I first started building, I had a SEGV in test-all occurring in TestEnumerable#test_callcc. I patched around it, but decided it was time to see if I could find a solution.

The issue occurs in test/ruby/test_enum.rb:559-570. Below is the code:

assert_raise(RuntimeError) do
  c = nil
  o =
  class << o; self; end.class_eval do
    define_method(:<=>) do |x|
      callcc {|c2| c ||= c2 }
  [o, o].sort_by {|x| x }

While trying to determine the problem in a separate test environment, I stumbled across an odd solution.

Add the line c.to_s immediately before the line. My system no longer stops.

I'd be happy to do a PR, but I can only test on Windows.

Two questions --

  1. Might all of tests that involve callcc or Continuation be moved into another test file? Since it is considered 'obsolete'... I'd be happy to do.

  2. Rather odd that this fixes the issue. Any ideas?

--- test/ruby/test_enum.rb.orig	Thu Mar 09 07:54:37 2017
+++ test/ruby/test_enum.rb	Thu Mar 09 11:39:07 2017
@@ -568,2 +568,3 @@
       [o, o].sort_by {|x| x }
+      c.to_s


test_enum_559.txt (10.6 KB) test_enum_559.txt MSP-Greg (Greg L), 03/09/2017 08:56 PM
x64-mingw32-callcc-test.rb (434 Bytes) x64-mingw32-callcc-test.rb Repro derived from `TestHash#test_callcc` in `test/ruby/test_hash.rb` xtkoba (Tee KOBAYASHI), 06/04/2021 01:14 AM

Updated by MSP-Greg (Greg L) almost 6 years ago

Added SEGV log.

Also, listed method calls sort with two items, and faults. Next call does the same with three items. No error. Hence,

  1. Any ideas?

Updated by shyouhei (Shyouhei Urabe) almost 6 years ago

  • Status changed from Open to Assigned
  • Assignee set to nobu (Nobuyoshi Nakada)

Updated by xtkoba (Tee KOBAYASHI) over 1 year ago

I have a similar problem with a recent 3.1.0dev version, in which the attached test case (named x64-mingw32-callcc-test.rb) dies silently.

I suppose that the code inserted by a6ae274c3b06174401276fde2636f17720508532 (dated Jul 8 2007) interacts badly with __builtin_setjmp (and __builtin_longjmp) from x64-mingw32. The following change seems to make the test case work as expected.

--- a/cont.c
+++ b/cont.c
@@ -1388,6 +1388,9 @@
     /* restore machine stack */
 #ifdef _M_AMD64
+# if defined __MINGW32__ && !defined RUBY_JMP_BUF
+    if (0)
+# endif
         /* workaround for x64 SEH */
         jmp_buf buf;

The expected result is as follows:

C:\CIFS\x64-mingw32>ruby ..\x64-mingw32-callcc-test.rb
C:/CIFS/x64-mingw32/lib/ruby/3.1.0/x64-mingw32/ warning: callcc is obsolete; use Fiber instead

C:\CIFS\x64-mingw32>ruby -v
ruby 3.1.0dev (2021-06-02T15:07:44Z master 2a685da1fc) [x64-mingw32]

Updated by xtkoba (Tee KOBAYASHI) over 1 year ago

Note that there are two related issues, for which the solutions conflict with each other:

  • #9710: no __builtin_setjmp on x64-mingw
  • #15348: use __builtin_setjmp on mingw64

Updated by ioquatix (Samuel Williams) about 1 month ago

I also found that the if (0) is required in Ruby 3.2 in order to build locally in the Ruby Installler Dev Kit otherwise it crashes as indicated.

Updated by ioquatix (Samuel Williams) about 1 month ago

  • Status changed from Assigned to Closed

I've merged which is similar to the above proposal.

It fixes a repeatable segfault on my local Windows 11 development VM.


Also available in: Atom PDF