Project

General

Profile

Actions

Bug #20666

open

Segmentation fault instead of LoadError exception

Added by ErezGeva2@gmail.com (Erez Geva) 9 days ago. Updated 2 days ago.

Status:
Open
Assignee:
-
Target version:
-
ruby -v:
ruby 3.2.5 (2024-07-26 revision 31d0f1a2e7) [x64-mingw-ucrt]
[ruby-core:118791]

Description

Using ruby -v
ruby 3.2.5 (2024-07-26 revision 31d0f1a2e7) [x64-mingw-ucrt]

From GitHub windows 2022

We run the SWIG test:
import_fragments
The test try to load a broken library, which should rise a LoadError.

begin
  require 'import_fragments'
rescue LoadError => e
  # due to missing import_fragments_a
  exception_file = e.respond_to?(:path) ? e.path : e.to_s.sub(/.* -- /, '')
end

Instead LoadError exception we get Segmentation fault:

<internal:C:/hostedtoolcache/windows/Ruby/3.2.5/x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:151: [BUG] Segmentation fault
ruby 3.2.5 (2024-07-26 revision 31d0f1a2e7) [x64-mingw-ucrt]

-- Control frame information -----------------------------------------------
c:0004 p:0018 s:0028 e:000025 RESCUE <internal:C:/hostedtoolcache/windows/Ruby/3.2.5/x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:151
c:0003 p:0275 s:0022 e:000021 METHOD <internal:C:/hostedtoolcache/windows/Ruby/3.2.5/x64/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:40
c:0002 p:0011 s:0007 E:0004e8 EVAL   ./import_fragments_runme.rb:13 [FINISH]
c:0001 p:0000 s:0003 E:0006e0 DUMMY  [FINISH]

Files

source.zip (20.2 KB) source.zip Source code ErezGeva2@gmail.com (Erez Geva), 08/07/2024 09:38 PM
small_ruby_test_log.zip (6.09 KB) small_ruby_test_log.zip small ruby test log files ErezGeva2@gmail.com (Erez Geva), 08/11/2024 09:54 AM

Updated by alanwu (Alan Wu) 6 days ago

  • Status changed from Open to Feedback

With big and complex native extensions like SWIG, the problem is probably not in Ruby itself. The reproducer you provide is also probably too large to expect volunteers to diagnose. Maybe you should report this to SWIG, or minimize the reproducer to demonstrate that it happens without SWIG?

Updated by ErezGeva2@gmail.com (Erez Geva) 5 days ago

I do add the new Ruby to the SWIG project testing.
If I would suspect it is a SWIG bug, I would not hesitate and report it there.

The same test works with older Ruby:
ruby 3.1.6p260 (2024-05-29 revision a777087be6) [x64-mingw-ucrt]

See:
https://github.com/swig/swig/actions/runs/10263993827/job/28397046211?pr=2981

The test generate a wrapper code with SWIG
and build it into a shared library.
Which the Ruby try to load and should issue a LoadError exception.

Both tests use the same GCC compiler:
GCC MinGW-W64 ucrt64, Rev1, Built by MSYS2 project) 14.2.0

The SWIG generate the same code.
So the generated shared library can only differ in Ruby headers!

As far as I understand, the only change is using Ruby 3.2.5 on Windows.

By the way we also run the same test on Linux,
with Ruby:
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-linux]

See:
https://github.com/swig/swig/actions/runs/10263993829/job/28397064713?pr=2981

I do understand it may be difficult to test something like that alone.
Yet, I do not have a Windows machine myself.

But I can help in:

  1. Generate the SWIG code.
  2. Provide the commands to build the shared library using GCC MinGW-W64 ucrt64
  3. Provide the ruby script
  4. Provide the ruby command running the test itself.

If that helps you to catch the BUG, please tell me and I will upload them here.

Erez

Updated by ErezGeva2@gmail.com (Erez Geva) 5 days ago

Include in source.zip are:

  1. import_fragments_runme.rb
  2. import_fragments_wrap.cxx
  3. swig_assert.rb

To build shared library using MinGW-w64 ucrt64:
g++ -c -std=c++20 import_fragments_wrap.cxx -I<Ruby dir> -I<Ruby arch dir>
g++ -shared -std=c++20 import_fragments_wrap.o -L<Ruby lib dir> -l<Ruby lib> <RbConfig::CONFIG["LIBS"]> -o import_fragments.so

And running:
ruby -I. ./import_fragments_runme.rb

A long story short:
import_fragments_runme.rb do require 'import_fragments
The shared library in Init_import_fragments(void)
call rb_require("import_fragments_a")
And import_fragments_a does not exist!

Note: Perhaps we are building wrongly, or we might need changes in our source code due to changes in Ruby 3.2.5.
I never role that the problem comes from SWIG.
But unlikely as all the reset of the SWIG tests with Ruby 3.2.5 on Windows pass!

Actions #4

Updated by alanwu (Alan Wu) 5 days ago

  • Status changed from Feedback to Open

Updated by alanwu (Alan Wu) 5 days ago

Note: Perhaps we are building wrongly, or we might need changes in our source code due to changes in Ruby 3.2.5.

Does it crash if you build the extension using mkmf? It seems mkmf should pass a different set of build flags than you are.

Updated by ErezGeva2@gmail.com (Erez Geva) 5 days ago

Testing with mkmf

It is worse.
I build the extension in Test using mkmf.
Now both Ruby issue a Segmentation fault.
Ruby 3.1.6 and Ruby 3.2.5.
See:
https://github.com/erezgeva/swig/actions/runs/10300870708

Using -L<Ruby lib dir> -l<Ruby lib> <RbConfig::CONFIG["LIBS"]>
Works with the older Ruby 3.1.6
See:
https://github.com/swig/swig/actions/runs/10263993827/job/28397046211?pr=2981
In Test
checking ruby testcase import_fragments (with run test)
Pass without any error.

Build with mkmf

I already send the code.
To build with mkmf
The name of the extension is import_fragments
An extconf.rb would look like:

require 'mkmf'
create_header
create_makefile 'import_fragments'

The source code import_fragments_wrap.cxx have the initialising function void Init_import_fragments(void).

Just for clarification:
I test with MinGW-w64 with ucrt64.

/ucrt64/bin/gcc
gcc.exe (Rev1, Built by MSYS2 project) 14.2.0
/ucrt64/bin/g++
g++.exe (Rev1, Built by MSYS2 project) 14.2.0

I install it with MSYS2, with the mingw-w64-ucrt-x86_64-gcc package.

Updated by ErezGeva2@gmail.com (Erez Geva) 2 days ago ยท Edited

Did some minimising.

Three sources:

extconf.rb

require 'mkmf'
create_header
create_makefile 'good'

good.cpp

#include <ruby.h>
extern "C" void Init_good(void) {rb_require("bad");}

load.rb

begin
require 'good'
rescue LoadError => e
print "#{e.to_s}\n"
end

Result on Linux

$ ruby extconf.rb; make; ruby -I. load.rb; echo $?

creating extconf.h
creating Makefile
compiling good.cpp
linking shared-object good.so
cannot load such file -- bad
0

We catch the LoadError exception and exit gracefully.

Result on Windows

Using the same Ruby 3.1.6 and Ruby 3.2.5 with GCC MinGW-W64 ucrt64
We run the same test in small ruby test.
We get Segmentation fault.
Attach are the log files of the small ruby test.

You can find the tests on github:
https://github.com/erezgeva/swig/actions/runs/10338780577

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0