Broken calling convention for callbacks from C into Haskell
Summary
The calling convention for callbacks from C into Haskell seem to be broken for at least some functions (alignment may play a role) with more than 6 parameters on x86_64 linux.
I've noticed that if the function's parameters are all 64-bits, then all of them reach the callback just fine. If one of the parameters is 32-bits, then the 7th parameter's value is lost and replaced with garbage (might be the return address). If two of the parameters are 32-bits, then the 7th parameter receives garbage, and then every parameter thereafter receives the previous parameter's value.
I've confirmed the problematic behavior occurs in GHC 9.4.8 and 9.6.3, but could not test in 9.8.1. The problem did not exist in 9.0.2, but I don't know in which specific version it first appeared.
@mniip found these, which might be relevant:
Steps to reproduce
I've uploaded a small repo to reproduce the behavior here: https://github.com/Rotaerk/ghcCallbackBugRepro/. If you can use nix flakes, then in the root folder do nix develop .#ghc948
, followed by cabal run
. You can exit
this nix shell and then repeat this with nix develop .#ghc902
to see that the problematic behavior didn't exist in that older version.