Skip to content

Regression when reading files via TH in windows (ucrt64) cross compilation on GHC 9.6/9.8/9.10 #2361

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
amesgen opened this issue May 16, 2025 · 3 comments
Labels
bug Something isn't working

Comments

@amesgen
Copy link
Member

amesgen commented May 16, 2025

Since #2354, reading files via TemplateHaskell for Windows cross-compilation (ucrt64; mingwW64 is broken before/after #2354) fails:

import qualified Language.Haskell.TH.Syntax as TH

main :: IO ()
main = putStrLn $(TH.lift =<< TH.runIO (readFile "app/foo.txt"))
stuff-exe-stuff-x86_64-w64-mingw32> [1 of 1] Compiling Main             ( app/Main.hs, dist/build/stuff/stuff-tmp/Main.o )
stuff-exe-stuff-x86_64-w64-mingw32> ---> Starting iserv-proxy-interpreter.exe on port 6018
stuff-exe-stuff-x86_64-w64-mingw32> To re-use the same wine-prefix and remote-iserv, set the following environment variables:
stuff-exe-stuff-x86_64-w64-mingw32> export WINEPREFIX=/build/tmp.16k3RVb3C6
stuff-exe-stuff-x86_64-w64-mingw32> export REMOTE_ISERV=/build/tmp.ZABjVoLRvB
stuff-exe-stuff-x86_64-w64-mingw32> ---| iserv-proxy-interpreter.exe should have started on 6018
stuff-exe-stuff-x86_64-w64-mingw32> 004c:err:vulkan:vulkan_init_once Wine was built without Vulkan support.
stuff-exe-stuff-x86_64-w64-mingw32> 004c:err:systray:initialize_systray Could not create tray window
stuff-exe-stuff-x86_64-w64-mingw32> 0094:err:setupapi:SetupDefaultQueueCallbackW copy error 1812 L"@C:\\windows\\system32\\drivers\\wineusb.sys,-1" -> L"C:\\windows\\inf\\wineusb.inf"
stuff-exe-stuff-x86_64-w64-mingw32> wine: failed to open L"C:\\windows\\syswow64\\rundll32.exe": c0000135
stuff-exe-stuff-x86_64-w64-mingw32> 002c:err:setupapi:do_file_copyW Unsupported style(s) 0x10
stuff-exe-stuff-x86_64-w64-mingw32> 00f8:err:ntoskrnl:ZwLoadDriver failed to create driver L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\winebth": c00000e5
stuff-exe-stuff-x86_64-w64-mingw32> 002c:err:setupapi:SetupDiInstallDevice Failed to start service L"winebth" for device L"ROOT\\WINE\\WINEBTH", error 1359.
stuff-exe-stuff-x86_64-w64-mingw32> 002c:err:setupapi:SetupDiInstallDevice Failed to control service L"winebth" for device L"ROOT\\WINE\\WINEBTH", error 1062.
stuff-exe-stuff-x86_64-w64-mingw32> 002c:err:setupapi:do_file_copyW Unsupported style(s) 0x10
stuff-exe-stuff-x86_64-w64-mingw32> 0120:err:setupapi:do_file_copyW Unsupported style(s) 0x10
stuff-exe-stuff-x86_64-w64-mingw32> 0120:err:setupapi:do_file_copyW Unsupported style(s) 0x10
stuff-exe-stuff-x86_64-w64-mingw32> Listening on port 6018
stuff-exe-stuff-x86_64-w64-mingw32>
stuff-exe-stuff-x86_64-w64-mingw32> app/Main.hs:8:17: error: [GHC-87897]
stuff-exe-stuff-x86_64-w64-mingw32>     • Exception when trying to run compile-time code:
stuff-exe-stuff-x86_64-w64-mingw32>         app/foo.txt: hGetContents: invalid argument (Bad file descriptor)
stuff-exe-stuff-x86_64-w64-mingw32>       Code: (TH.lift =<< TH.runIO (readFile "app/foo.txt"))
stuff-exe-stuff-x86_64-w64-mingw32>     • In the untyped splice:
stuff-exe-stuff-x86_64-w64-mingw32>         $(TH.lift =<< TH.runIO (readFile "app/foo.txt"))
stuff-exe-stuff-x86_64-w64-mingw32>   |
stuff-exe-stuff-x86_64-w64-mingw32> 8 | main = putStrLn $(TH.lift =<< TH.runIO (readFile "app/foo.txt"))
stuff-exe-stuff-x86_64-w64-mingw32>   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
stuff-exe-stuff-x86_64-w64-mingw32> ---> killing iserv-proxy-interpreter.exe...

This error occurs with GHC 9.6.7 and GHC 9.8.4 and 9.10.2; with 9.12.2, it seems to work fine.

Minimal reproducible example

https://github.com/amesgen/stuff/tree/haskell.nix-windows-TH-readFile

008e8ccf Bump nixpkgs pins (#2354)
e9854532 Update Hackage and Stackage

Running this command reproduces the bug, using haskell.nix at 008e8cc:

nix build github:amesgen/stuff/haskell.nix-windows-TH-readFile#bad

This command runs with haskell.nix at e985453, which works fine, demonstrating that #2354 introduced the regression:

nix build github:amesgen/stuff/haskell.nix-windows-TH-readFile#good
@amesgen amesgen added the bug Something isn't working label May 16, 2025
@amesgen amesgen changed the title Regression when reading files via TH in windows cross compilation Regression when reading files via TH in windows (ucrt64) cross compilation May 16, 2025
@amesgen amesgen changed the title Regression when reading files via TH in windows (ucrt64) cross compilation Regression when reading files via TH in windows (ucrt64) cross compilation on GHC 9.6 May 16, 2025
@amesgen amesgen changed the title Regression when reading files via TH in windows (ucrt64) cross compilation on GHC 9.6 Regression when reading files via TH in windows (ucrt64) cross compilation on GHC 9.6/9.8/9.10 May 16, 2025
@thomasjm
Copy link
Contributor

See also #2314

@angerman
Copy link
Collaborator

@amesgen thanks for the report. I remember seeing this ...

app/foo.txt: hGetContents: invalid argument (Bad file descriptor)

iirc this was due to mixing msvcrt and ucrt runtimes somewhere.

@hamishmack
Copy link
Collaborator

This is proving hard to track down.

Just adding --override-input haskellNixBad/nixpkgs-unstable to point to an older nixpkgs makes the "bad" build work.

A git bisect of nix build ../stuff#bad -L --override-input haskellNixBad/nixpkgs-unstable . gave:

$ git bisect log
git bisect start
# good: [84e9ff035338219500577ff6868a23fe6d55f34e] wine: fix stable / yabridge builds with binutils 2.44 (#401107)
git bisect good 84e9ff035338219500577ff6868a23fe6d55f34e
# bad: [b3582c75c7f21ce0b429898980eddbbf05c68e55] chromium,chromedriver: 136.0.7103.59 -> 136.0.7103.92 (#404779)
git bisect bad b3582c75c7f21ce0b429898980eddbbf05c68e55
# good: [cb18e5e1e118a5d83cc0ac2c3a5988fd260e4371] _1password-gui: 8.10.72 -> 8.10.75 (#403083)
git bisect good cb18e5e1e118a5d83cc0ac2c3a5988fd260e4371
# bad: [36598c241f78baad218fc45420b88296eac96b40] Merge master into staging-next
git bisect bad 36598c241f78baad218fc45420b88296eac96b40
# bad: [b07044de37a3dd62abc0cd3d25ba276f823e1fac] gawk: 5.3.1 -> 5.3.2 (#395475)
git bisect bad b07044de37a3dd62abc0cd3d25ba276f823e1fac
# good: [eecfdda93dc44a58686a82bd7536d5e6e3a0cae8] haskellPackages: fix some builds (#397451)
git bisect good eecfdda93dc44a58686a82bd7536d5e6e3a0cae8
# good: [735e527e4d191169e3d6d40c1b0153205497ee69] openssh: 9.9p2 -> 10.0p2 (#397626)
git bisect good 735e527e4d191169e3d6d40c1b0153205497ee69
# bad: [6b5466614330faee99a80438d99c10b2f87e0c82] Merge staging-next into staging
git bisect bad 6b5466614330faee99a80438d99c10b2f87e0c82
# bad: [5ec4cb13653b770df8ec7941a3c646163217b274] Merge staging-next into staging
git bisect bad 5ec4cb13653b770df8ec7941a3c646163217b274
# bad: [deb427c42b50c779876f2de90b8199f6fb218477] Merge staging-next into staging
git bisect bad deb427c42b50c779876f2de90b8199f6fb218477
# good: [27f5e49d9735832d3235d73ea88cb0c12684e26e] Merge staging-next into staging
git bisect good 27f5e49d9735832d3235d73ea88cb0c12684e26e
# good: [4eaf9c28fb78aea3107ba11ae5f57dc3fc939de3] gnupg: fix availability of libexec tools (#395155)
git bisect good 4eaf9c28fb78aea3107ba11ae5f57dc3fc939de3
# good: [495f4b96d29a23e6ed51d2b427a9fbc77e7976f1] Merge remote-tracking branch 'origin/staging-next' into staging
git bisect good 495f4b96d29a23e6ed51d2b427a9fbc77e7976f1
# bad: [0fbbdaa9e0eefe8cff206add0efb1842a76f1282] perl: filter out reference to `apple-sdk` package (#386700)
git bisect bad 0fbbdaa9e0eefe8cff206add0efb1842a76f1282
# bad: [41d308656773689b4adb47337aa9caf7f771ba4e] perl: filter out reference to `apple-sdk` package
git bisect bad 41d308656773689b4adb47337aa9caf7f771ba4e
# first bad commit: [41d308656773689b4adb47337aa9caf7f771ba4e] perl: filter out reference to `apple-sdk` package

However it seems that NixOS/nixpkgs@41d3086 is not related to the TH failure. It just forces everything to be rebuilt (it changes postInstall for perl slightly and that results in almost everything rebuilding).

It seems like the success/failure depends on something nondeterministic in the build output for the iserv-proxy-interpreter.exe. Just swapping in the "good" version of that .exe was enough to make the "bad" version work (at least for the41d30865 and its working parent).

Here is a version of app/Main.hs that fails more directly (no lazy IO):

{-# LANGUAGE TemplateHaskell #-}
module Main where

import qualified Language.Haskell.TH.Syntax as TH

import GHC.IO.IOMode
import qualified GHC.IO.FD as FD
import GHC.IO.Device as IODevice
import Foreign
import Foreign.C.Types

main :: IO ()
main = putStrLn $(TH.lift =<< TH.runIO (do
  putStrLn "HELLO"
  (fd, _) <- FD.openFile "app/foo.txt" ReadMode True
  -- IODevice.ready fd False 100 >>= print  -- Works fine
  ptr <- mallocBytes 100
  x <- IODevice.read fd ptr 0 1 -- Fails here
  print x
  c <- peekArray x ptr
  print c
  return $ show c))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants