Skip to content

fix: switch CharacterMode from RGui to LinkDLL to prevent system() hang on Windows#117

Merged
eitsupi merged 4 commits intomainfrom
fix/windows-system-hang-linkdll
Mar 17, 2026
Merged

fix: switch CharacterMode from RGui to LinkDLL to prevent system() hang on Windows#117
eitsupi merged 4 commits intomainfrom
fix/windows-system-hang-linkdll

Conversation

@eitsupi
Copy link
Copy Markdown
Owner

@eitsupi eitsupi commented Mar 17, 2026

Summary

  • Switch CharacterMode from RGui to LinkDLL after R_SetParams() to fix system()/system2() hanging indefinitely on Windows
  • R's do_system() invalidates standard handles via SetStdHandle(INVALID_HANDLE_VALUE) when CharacterMode is RGui, causing child processes to hang
  • This follows the same pattern used by sircon
  • Fix libloading symbol loading for Windows global int variables — get::<c_int>() (4 bytes) silently failed the size_of::<T>() == size_of::<FARPROC>() check (8 bytes on 64-bit), returning null pointers for CharacterMode, R_Interactive, R_SignalHandlers, and R_running_as_main_program

Test plan

  • On Windows, run system("echo hello") and confirm it completes without hanging
  • On Windows, run Rcpp::cppFunction("int add(int x, int y) { return x + y; }") and confirm compilation succeeds
  • Verify pager (:help print), help display, and menu() still work correctly

Closes #116

eitsupi and others added 2 commits March 17, 2026 03:03
…ng on Windows

R's do_system() invalidates standard handles (SetStdHandle with
INVALID_HANDLE_VALUE) when CharacterMode is RGui, causing system() and
system2() calls to hang indefinitely on Windows.

Fix by switching CharacterMode to LinkDLL after R_SetParams() but
before setup_Rmainloop(), following the same pattern used by sircon.
This keeps the console callback setup from RGui mode while avoiding
the handle invalidation in do_system().

Closes: #116

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Add compile-time assert that UImode (repr(u32)) matches c_int size
- Upgrade log level from warn to error when CharacterMode symbol
  cannot be loaded, since system() will hang without it

Co-Authored-By: Claude Opus 4.6 <[email protected]>
eitsupi and others added 2 commits March 17, 2026 03:46
libloading's Windows get::<T>() requires size_of::<T>() ==
size_of::<FARPROC>() (8 bytes on 64-bit). Using c_int (4 bytes) caused
IncompatibleSize error, silently returning null pointers for all global
int variables (R_Interactive, R_SignalHandlers, R_running_as_main_program,
CharacterMode).

This was the root cause of CharacterMode failing to load, which meant
the RGui-to-LinkDLL switch never happened and system() still hung.

Fix by using get::<usize>() with try_as_raw_ptr() to obtain the symbol
address without the size constraint.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
The try_as_raw_ptr() calls are already inside an outer unsafe block,
so inner unsafe blocks are redundant and trigger warnings.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@eitsupi eitsupi changed the title fix: switch CharacterMode from RGui to LinkDLL to prevent system() hang on Windows fix: switch CharacterMode from RGui to LinkDLL to prevent system() hang on Windows Mar 17, 2026
@eitsupi eitsupi merged commit 3a60760 into main Mar 17, 2026
10 checks passed
@eitsupi eitsupi deleted the fix/windows-system-hang-linkdll branch March 17, 2026 22:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

system() hangs on Windows

1 participant