Skip to content

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.

Edited by rotaerk
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information