A plugin's DynFlags not properly shared with GHC under Windows?
This is a summary of conclusions from the investigations below.
When the host compiler is a statically linked executable (eg, under Windows), the host compiler and (the set of all) plugins seem to have distinct copies of global variables. The plugins DynFlags do not seem to be initialised reliably.
There used to be a similar issue https://gitlab.haskell.org/ghc/ghc/-/wikis/plugins/reinitialize-globals that seems to have been addressed in recent versions of GHC (so there is only one set of globals shared by ghc and the plugins).
However, that fix doesn't seem to work reliably in this case. The issue may involve the
SHARED_GLOBAL_VAR logic which backs
unsafeGlobalDynFlags since there may be some linker trickiness involved there.
When a plugin is loaded, it currently gets linked against a newly loaded copy of the GHC package. This would not be a problem, except that the new copy has its own mutable state that is not shared with that state that has already been initialized by the original GHC package.
(Note that if the GHC executable was dynamically linked this wouldn't be a problem, because we could share the GHC library it links to; this is only a problem if DYNAMIC_GHC_PROGRAMS=NO.)
The solution is to make use of @sharedCAF@ through @sharedGlobal@ for globals that are shared between multiple copies of ghc packages.
sharedGlobal is not working correctly under Windows.
When I try to
liftIO $ writeFile path content from within a typecheck result plugin, running under Windows, I get
ghc.exe: panic! (the 'impossible' happened) (GHC version 8.10.1: v_unsafeGlobalDynFlags: settings not initialised
The code works without problem on MacOS and Linux, writing out the expected content. On Windows, I get an empty file and the panic above.
content is just a
String, of course, and I have
liftIO $ setLocaleEncoding utf8.
Presumably the right default dflags are not being set for the plugin or, more likely, not being picked up correctly in the entrails of the writing routines.
Is there a workaround? What is the recommended way of sticking a utf8 string back out into a file in a way that I can pass the dflags explicitly?
- GHC version used: 8.10.1, probably 8.8.3
- Operating System: Windows 10 2004
- System Architecture: x64