Bug #18605


Fails to run on (newer) 32bit Windows with ucrt

Added by lazka (Christoph Reiter) 9 months ago. Updated about 1 month ago.

Target version:


32bit ruby using ucrt has started to fail on newer Windows with "unexpected ucrtbase.dll" ->

The problem is that ruby depends on ucrt internals and those have apparently changed with newer versions.

See and for some background and a potential fix. But ideally ruby wouldn't depend on Windows internals like this.


Related issues 1 (0 open1 closed)

Related to Ruby master - Bug #11118: Unable to build Ruby with Visual Studio 2015 RCClosedActions
Actions #1

Updated by naruse (Yui NARUSE) 8 months ago

  • Related to Bug #11118: Unable to build Ruby with Visual Studio 2015 RC added

Updated by naruse (Yui NARUSE) 8 months ago

Why Ruby depends to _pioinfo is

  • to associate socket and fd: CRuby creates fd with dummy file handle and set socket to emulate Unix-like behavior
  • to implement overlapped I/O for Windows 2000/XP
  • to emulate fcntl(2)

If you know a better way to implement above use cases, we will migrate to that.


Updated by ivall (ivall ivall) about 2 months ago

I have same problem on Windows 11 25206, reinstalling Ruby didn't help.

Updated by MSP-Greg (Greg L) about 2 months ago

An issue exists elsewhere, see I'm just the messenger, I don't have the knowledge needed for this issue.

Quoting the response from ArminG-MSFT:

Hello this is Armin from Microsoft. We encountered the same or at least a very similar issue in our internal compatibility testing. What seems to be the issue is that Ruby is relying on undocumented/unsupported behaviour. It is trying to retrieve a pointer to an internal variable __pioinfo inside urtbase.dll. That itself is not supported, but from our debugging and looking at the code in win32.c it looks like it is doing it by walking back from the ret assembly instruction in _isatty(). But this assumes the ret instruction will be the last instruction in that _isatty().

The issue is that certain optimizations can move function code beyond a ret instruction, so the common/typical instruction path is shorter. And new optimizations we applied to recent ucrtbase.dll builds did exactly that in _isatty(). So it looks like Ruby is now looking at the wrong location and no longer finding __pioinfo.

Short term we'll be rolling out a fix that for this function that undoes this optimization, which should fix this specific error for the many Ruby users in the wild. But it would be great if Ruby can be fixed to not use undocumented behaviour, or perhaps at least be more robust in its function traversal. Note though that at some point we may break it in some way that is not so easily fixed.

The offending code is in win32\win32.c function set_pioinfo_extra.

Feel free to correct me though if our understanding is incorrect.

Updated by lazka (Christoph Reiter) about 1 month ago

This (unsurprisingly) also breaks ruby on arm64 and is blocking our arm64 porting effort:


Also available in: Atom PDF