Bug #20666
openSegmentation fault instead of LoadError exception
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
Updated by alanwu (Alan Wu) 4 months 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) 4 months 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:
- Generate the SWIG code.
- Provide the commands to build the shared library using GCC MinGW-W64 ucrt64
- Provide the ruby script
- 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) 4 months ago · Edited
- File source.zip added
source.zip added
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!
Updated by alanwu (Alan Wu) 4 months 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) 4 months ago · Edited
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.
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) 3 months ago · Edited
- File small_ruby_test_log.zip small_ruby_test_log.zip added
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
Updated by ErezGeva2@gmail.com (Erez Geva) 3 months ago
- File deleted (
source.zip)