Linking error on refactor---how to debug?

Hi all,

I recently made a refactor to a relatively simple project I’m creating. I hadn’t compiled the project in a while as I was using hls to catch compiler errors, and then some 200 edits later (as measured by git), when the refactor was complete, I found that the project was failing to compile in the linking stage. You can see below for an abridged version of the error message.

In case it’s helpful, the refactor largely involved the creation of a newtype to separate logic to do with that type into its own module.

So far I have tried:

  • Compiling on macOS and x86-64 linux.
  • Compiling from a “clean” environment, i.e. after running cabal clean.
  • Downgrading ghc, since cabal doesn’t claim to support the version I’ve been developing in (9.4.7).

None of the above changed the error significantly. I thought it might be best to ask here before I go any further: does anyone have any ideas for debugging the error, apart from incrementally rolling back changes? I will do that in the worst case but want to avoid it if possible since the number of edits since the last successful compilation is decently large.

Here’s the error log:

Linking <working dir>/dist-newstyle/build/x86_64-linux/ghc-9.2.8/haculator-0.1.0.0/x/haculator/build/haculator/haculator ...
ld.lld: error: undefined symbol: haculatorzm0zi1zi0zi0zminplace_CalculatorziLinearExpression_expo_closure
>>> referenced by Calculator.o:(haculatorzm0zi1zi0zi0zminplace_Calculator_evalExpo_info) in archive <working dir>/dist-newstyle/build/x86_64-linux/ghc-9.2.8/haculator-0.1.0.0/build/libHShaculator-0.1.0.0-inplace.a
>>> referenced by Calculator.o:(.data+0x188) in archive <working dir>/dist-newstyle/build/x86_64-linux/ghc-9.2.8/haculator-0.1.0.0/build/libHShaculator-0.1.0.0-inplace.a

ld.lld: error: undefined symbol: haculatorzm0zi1zi0zi0zminplace_CalculatorziLinearExpression_expozuzdssingle_closure
>>> referenced by Calculator.o:(.text+0xBF4) in archive <working dir>/dist-newstyle/build/x86_64-linux/ghc-9.2.8/haculator-0.1.0.0/build/libHShaculator-0.1.0.0-inplace.a
>>> referenced by Calculator.o:(.text+0xC34) in archive <working dir>/dist-newstyle/build/x86_64-linux/ghc-9.2.8/haculator-0.1.0.0/build/libHShaculator-0.1.0.0-inplace.a
>>> referenced by Calculator.o:(.data+0x198) in archive <working dir>/dist-newstyle/build/x86_64-linux/ghc-9.2.8/haculator-0.1.0.0/build/libHShaculator-0.1.0.0-inplace.a

<<<more undefined symbols>>>

ld.lld: error: undefined symbol: haculatorzm0zi1zi0zi0zminplace_CalculatorziLinearExpression_addzuzdsunionWithDefault_closure
>>> referenced by Calculator.o:(.data+0x130) in archive <working dir>/dist-newstyle/build/x86_64-linux/ghc-9.2.8/haculator-0.1.0.0/build/libHShaculator-0.1.0.0-inplace.a
>>> referenced by Calculator.o:(.data+0x150) in archive <working dir>/dist-newstyle/build/x86_64-linux/ghc-9.2.8/haculator-0.1.0.0/build/libHShaculator-0.1.0.0-inplace.a
>>> referenced by Calculator.o:(.data+0x278) in archive <working dir>/dist-newstyle/build/x86_64-linux/ghc-9.2.8/haculator-0.1.0.0/build/libHShaculator-0.1.0.0-inplace.a

ld.lld: error: too many errors emitted, stopping now (use --error-limit=0 to see all errors)
collect2: error: ld returned 1 exit status
`gcc' failed in phase `Linker'. (Exit code: 1)

And here’s the offending commit. Thanks very much for any help in advance! :slight_smile:

Have you tried clearing the cabal or stack cache (whichever you’re using. I think it’s cabal?)
This kind of looks like weird errors I sometimes get after interrupting a compilation and the cache or objects already produced are bad/corrupted.

If a compilation with your current code from a “clean environment” doesn’t work, than I don’t know what this might be :man_shrugging:

I have, assuming cabal clean does what you’re referring to. Thanks for the suggestion, though!

Or just completely remove the dist-newstyle folder, just to be sure.
Though that will mean you might have to recompile “everything” (for some value of “everything”)

One of the things cabal clean does is just that :slight_smile:

1 Like

Cannot see any reason why that commit would change linking behaviour…

I don’t know how HLS works internally, but I suspect its cache too neds some cleaning.

As far as I can tell, hls is doing its job just fine—the individual modules compile without issue, and I can’t imagine it’s hls’ responsibility to detect linking errors.

You get this error if you don’t include a source file by it’s module name to the list of modules in your .cabal file. Most of the time you get a GHC error saying you should include the module in the cabal file and it works anyway, but not always (could be that it doesn’t work with exposed-modules).
HLS works without that, the samé just happened to me some days ago.

Looking at your project, your Calculator. LinearExpressions module is not mentioned in the cabal file - you also see that in the (mangled) names of the linker error

3 Likes

Ahh! Thank you! I could very easily have spent hours rolling back changes without thinking to check there. Very grateful to have skipped that :slight_smile:

1 Like

GHC letting this kind of error through to the linker stage sounds like a bug to me…

2 Likes

See #8902.

Ideas on how to make UX better and maybe even a PR are always welcome!

4 Likes

This isn’t a Haskell-specific answer, but you could use git bisect to find out where the problem crept in. If there are n commits to search, this will find the problem in O(log n) steps.

4 Likes