Implement bindings to ruby_sysinit and ruby_init_stack (Segmentation fault in Windows on VM#init)
somedevfox opened this issue · 0 comments
somedevfox commented
Hello all,
Description of issue
Rutie is missing bindings to Virtual Machine Initialization methods such as ruby_sysinit
and ruby_init_stack
which are vital on Windows New Technology Operating Systems.
If one does not use them, they will get STATUS_ACCESS_VIOLATION
(Segmentation Fault) on Ruby 3.1 (and on previous versions, perhaps?).
Host information
OS Version: Windows 10 21H2 (19044.1889)
Rust Version: 1.65.0-nightly
Linked with Ruby Version: 3.1
Steps to reproduce STATUS_ACCESS_VIOLATION
- Install dependencies
- Install Chocolatey Package Manager
- Install Ruby:
choco install ruby
in PowerShell (As Administrator)
- Install Ruby:
- Install MSYS2 UNIX Environment
- Install CSFML (UCRT64):
pacman -S mingw-w64-ucrt-x86_64-csfml
in MSYS2 Shell / UCRT64 Subsystem
- Install CSFML (UCRT64):
- Clone rcxp
- Run in shell
cargo run
error: process didn't exit successfully: 'target\debug\rcxp.exe' (exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)
Method signatures and their descriptions:
// ruby/interpreter.h
/**
* Initializes the process for libruby.
*
* This function assumes this process is `ruby(1)` and it has just started.
* Usually programs that embed CRuby interpreter may not call this function,
* and may do their own initialization.
*
* @param[in] argc Pointer to process main's `argc`.
* @param[in] argv Pointer to process main's `argv`.
* @warning `argc` and `argv` cannot be `NULL`.
*
* @internal
*
* AFAIK Ruby does write to argv, especially `argv[0][0]`, via setproctitle(3).
* It is intentional that the argument is not const-qualified.
*/
void ruby_sysinit(int *argc, char ***argv);
/**
* Set stack bottom of Ruby implementation.
*
* You must call this function before any heap allocation by Ruby
* implementation. Or GC will break living objects.
*
* @param[in] addr A pointer somewhere on the stack, near its bottom.
*/
void ruby_init_stack(volatile VALUE *addr);
And I'm pretty sure they're needed, since I also tried initializing Ruby Virtual Machine from Pure C and it didn't work without at least ruby_sysinit
.
So, there are two options.
- Implement
VM#init_sys
- ruby_sysinit andVM#init_stack
- ruby_init_stack, requiring Rutie Dev to use them before VM Initialization. - Instead of implementing two new methods, we can modfy
VM#init
to use these functions internally, freeing the developer from additional code.
What's the better way to go around this?