On Fri, 23 May 2025, Yuyi Wang wrote:

> On Wed, 22 May 2025, Jeremy Drake wrote:
> > Ultimately, playing whack-a-mole in a 64-bit address space hoping that the
> > DLL will load in the same place as the parent is an exercise in futility,
> > especially in only 6 attempts.
>
> Outside cygwin, rustc also try 5 times to load the proc macro DLL, so there 
> are
> 30 attempts.

No, these retries are done on fork in the child, before control is
returned to the caller of fork.

> Could this issue be solved by running rebaseall on binaries in
> `/usr/bin`? Should we introduce `rebase` to rustc?

Maybe.  MSYS2 doesn't generally advise to rebase on x86_64, but I think
Cygwin does as part of its setup/postinstall hooks.  As a hack, I was able
to work around this by setting the "dynamicbase" flag on the dlls (it's a
long story about why this helps rather than hurts in this particular case)

> Another idea: is it possible to provide an API to disable reload-on-fork of a
> specific DLL? Although it might be unsafe, I think it's OK here, because rustc
> just wants to execute the linker, and in this case the proc macro DLLs won't 
> be
> used in the new process.
>
> In rust-lang/rust#141276, Jeremy Drake wrote:
> > It seems like in most cases it'd probably use posix_spawn
>
> If I were right, posix_spawn also uses fork + exec. That's why I don't think
> switching to `Command::spawn` would solve this problem. However, the non-POSIX
> spawn* APIs don't use fork. I'm not sure if it worth a try. As it seems that 
> the
> linker is executed by LLVM, I think it may be better to patch LLVM.

posix_spawn currently does fork+exec under the hood.  It's on my TODO list
to try to optimize this to do a "spawn" instead in cases where the
attributes and file actions are not too complicated.  While I had this
situation in the debugger, I confirmed this case is going through
posix_spawnp, with all of the attributes fields 0, and 2 file actions
which are dup2s for stdout and stderr.  This should be perfectly fine to
implement through the ch_spawn worker, though no ability is currently
exposed through it to redirect stderr it is possible to do so through the
win32 apis so it's just a matter of exposing it in the internal api.

I was thinking today about trying to hack something together to do this,
but I don't know when I'll get time to do this, and for a real
implementation rather than a proof-of-concept hack I'd want to ask some
questions of Corinna on the best way forward.

Namely: the posix_spawn_file_actions_t and posix_spawnattr_t structs are
defined inside newlib/libc/posix/spawn.c.  While there seem to be
'getters' for the attrs, I don't see any public way to query the file
actions.

My plan was to make functions cygwin_posix_spawn and cygwin_posix_spawnp,
and redirect the exports in cygwin.din to these functions, and inspect the
parameters and decide if they were something that was easily doable with
ch_spawn or if we should forward the call to the original functions from
newlib to do fork/exec.  The issue is that these functions would need to
look at the file actions.  For a proof-of-concept I would copy/paste the
file actions structs from newlib, but I don't know what the best option
would be for doing so in a maintainable way.  Something to think about...

-- 
Problem reports:      https://cygwin.com/problems.html
FAQ:                  https://cygwin.com/faq/
Documentation:        https://cygwin.com/docs.html
Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple

Reply via email to