ghci gives ghc panic when using foreign c calls - haskell

I'm trying to use ghci / stack repl on a project where one module has foreign calls linked to a C lib tdsodbc, but I keep getting
ghc: panic! (the 'impossible' happened)
(GHC version 7.10.3 for x86_64-unknown-linux):
Loading temp shared object failed: /tmp/ghc4628_0/libghc_71.so: undefined symbol: SQLPrepareW
(where SQLPrepareW is defined in that C lib). Building with stack works fine. This happens even on other modules that just happen to import the foreign-calling module, even without actually calling the foreign functions. It doesn't happen on load, but as soon as I try to fully evaluate any function in the repl.
How can I tell ghci that some of the functions are defined in libs outside of ghc?
I've tried the -l option (e.g. stack exec ghci -- -ltdsodbc), but the only difference then is that a different function from the same lib is in the error message:
ghc: panic! (the 'impossible' happened)
(GHC version 7.10.3 for x86_64-unknown-linux):
Loading temp shared object failed: /tmp/ghc24107_0/libghc_25.so: undefined symbol: SQLDriverConnectW
Note that it's obviously checking for the lib when using -l, since if I misspell it, it'll say it can't find it:
$ stack exec ghci -- -L/usr/lib/x86_64-linux-gnu/odbc -ltdsodbctypo
Warning (added by new or init): Specified resolver could not satisfy all dependencies. Some external packages have been added as dependencies.
You can suppress this message by removing it from stack.yaml
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
<command line>: user specified .o/.so/.DLL could not be loaded (libtdsodbctypo.so: cannot open shared object file: No such file or directory)
Whilst trying to load: (dynamic) tdsodbctypo
Additional directories searched: /usr/lib/x86_64-linux-gnu/odbc
This is with
$ stack --version
Version 1.4.0, Git revision e714f1dd3fade19496d91bd6a017e435a96a6bcd (4640 commits) x86_64 hpack-0.17.0
I've also tried stack ghci --ghci-options '-ltdsodbc -fobject-code', but it also panics with undefined symbol: SQLPrepareW.

The nice folks in #haskell on freenode said maybe I should try passing -fobject-code to ghci. That didn't work. I tried :set and :seti to see if it was already set, but ghci didn't show anything about object code. (Doing :unset -fobject-code just gave Some flags have not been recognized: -fno-object-code.)
Then today I happened to look at my ~/.ghci for some other reason, and that did have :set -fobject-code, even though :set/:seti doesn't show that. Removing :set -fobject-code from my ~/.ghci took away the panic attacks, and I can now use functions from modules that import the module that defines foreign functions :)
Actually calling any of the foreign functions from ghci leads to a segfault (catchsegv log for the interested), but at least I can test the pure stuff now …

Related

How to get rid of annoying startup message from stack ghci?

I'm using stack ghci to start my REPL, based on the answer I got for my question on how to import a module installed with stack. This works fine, but I get initially a warning message Note: No local targets specified, so a plain ghci will be started with no package hiding or package options., followed by a bunch of suggestions about package hiding and options. My guess is that this is because I have not used stack init to setup a project, since I am still in the "playing around and learning" state and don't want a project yet. I have not found an explanation about the meaning of 'no local targets', but the effect to start a plain ghci is exactly what I want at that point. Is there a way to suppress this message? I looked at stack --help, but could not find something suitable.
As the Note (not warning) suggests, a plain ghci is started, which is rather uncommon situation when working with stack.
~$ stack ghci
Note: No local targets specified, so a plain ghci will be started with no package hiding or package options.
You are using snapshot: lts-14.12
If you want to use package hiding and options, then you can try one of the following:
* If you want to start a different project configuration than /home/username/.stack/global-project/stack.yaml, then you can use stack init to create a new stack.yaml for the packages in the
current directory.
* If you want to use the project configuration at /home/username/.stack/global-project/stack.yaml, then you can add to its 'packages' field.
Configuring GHCi with the following packages:
GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /tmp/haskell-stack-ghci/2a3bbd58/ghci-script
Prelude>
This means though that all you need to do to get the same behavior without the Note is just start ghci manually in the context of global stack environment:
~$ stack exec -- ghci
GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help
Prelude>
In case that you want to make sure some package is installed for "playing around and learning" in the ghci session you can supply them as --package arguments
~$ stack exec --package massiv -- ghci
atomic-primops> using precompiled package
cabal-doctest > using precompiled package
scheduler > using precompiled package
massiv > using precompiled package
Completed 4 action(s).
GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help
Prelude> import Data.Massiv.Array
Prelude Data.Massiv.Array>
stack exec --ghci as in lehins's answer did not work for me, but stack exec ghci did.

Where is the source of `GHC.Paths.*` value came from?

I am running stack version 1.1.2 x86_64 hpack-0.14.1
$ stack exec which ghc
Run from outside a project, using implicit global project config
Using resolver: lts-5.10 from implicit global project's config file: /home/wisut/.stack/global-project/stack.yaml
/home/wisut/.stack/programs/x86_64-linux/ghc-7.10.3/bin/ghc
but when using stack ghci with GHC.Paths it is return the wrong path
$ stack ghci
Run from outside a project, using implicit global project config
Using resolver: lts-5.10 from implicit global project's config file: /home/wisut/.stack/global-project/stack.yaml
Error parsing targets: The specified targets matched no packages. Perhaps you need to run 'stack init'?
Warning: build failed, but optimistically launching GHCi anyway
Configuring GHCi with the following packages:
GHCi, version 7.10.3: http://www.haskell.org/ghc/ :? for help
Ok, modules loaded: none.
Prelude> GHC.Paths.ghc
"/usr/bin/ghc-7.10.3"
I am running Arch linux with ghc 8.0.1 therefor there is no ghc-7 avaliable outside stack
[wisut#earth ~]$ which ghc
/usr/bin/ghc
[wisut#earth ~]$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.0.1
[wisut#earth ~]$ ls -al /usr/bin/ghc
lrwxrwxrwx 1 root root 9 May 24 18:28 /usr/bin/ghc -> ghc-8.0.1
Looking at GHC.Paths source, I have no idea where the value are from. Is it the ENV vars?
{-# LANGUAGE CPP #-}
module GHC.Paths (
ghc, ghc_pkg, libdir, docdir
) where
libdir, docdir, ghc, ghc_pkg :: FilePath
libdir = GHC_PATHS_LIBDIR
docdir = GHC_PATHS_DOCDIR
ghc = GHC_PATHS_GHC
ghc_pkg = GHC_PATHS_GHC_PKG
Running stack exec env didn't see anything.
$ stack exec env | grep -i ghc
Run from outside a project, using implicit global project config
GHC_PACKAGE_PATH=/home/wisut/.stack/global-project/.stack-work/installx86_64-linux/lts-5.10/7.10.3/pkgdb:/home/wisut/.stack/snapshots/x86_64-linux/lts-5.10/7.10.3/pkgdb:/home/wisut/.stack/programs/x86_64-linux/ghc-7.10.3/lib/ghc-7.10.3/package.conf.d
PATH=/home/wisut/.stack/global-project/.stack-work/install/x86_64-linux/lts-5.10/7.10.3/bin:/home/wisut/.stack/snapshots/x86_64-linux/lts-5.10/7.10.3/bin:/home/wisut/.stack/programs/x86_64-linux/ghc-7.10.3/bin:/home/wisut/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
How can I fix the wrong value? How to to config stack to make GHC.Paths return the correct one?
UPD
I tried running stack with --no-system-ghc and it didn't make any difference.
I tried to remove my ~/.cabal and ~/.stack folders. I had to do stack setup, and after stack re-installed the compiler it doesn't give me that wrong path, but it doesn't give me any path, the output of that command is now empty.
I have nothing special in any of Setup.hs too.
You are almost right, the GHC_ variables are CPP definitions coming from custom Setup.hs:
let buildinfo = emptyBuildInfo{
cppOptions = ["-DGHC_PATHS_GHC_PKG=" ++ show c_ghc_pkg,
"-DGHC_PATHS_GHC=" ++ show c_ghc,
"-DGHC_PATHS_LIBDIR=" ++ show libdir,
"-DGHC_PATHS_DOCDIR=" ++ show docdir ]
}
About your problem with wrong path, try to run stack --no-system-ghc ghci. If it still shows "/usr/bin/ghc-7.10.3" for GHC paths, then I suspect that you had GHC there when you compiled ghc-paths for GHC-7.10.3, and as stack is quite good in not rebuilding stuff, the old version of ghc-paths is still there. I don't know a way to rebuild a package in a snapshot, other then whiping ~/.stack and starting over; which might be a good idea. if you changed you global GHC stuff.
There is a related issue: Stop using system-ghc silently.

Yesod build error because of the duplicate definition for symbol "hsprimitive_memcpy"

I followed "Yesod quick start guide" to install Yesod in Windows 10.
But, when I issued the stack build command, it failed.
Environment
Windows 10 (64bits)
stack-0.1.5 (for Windows10 64bits)
Haskell Platform 7.10.2-a (from HaskellPlatform-7.10.2-a-x86_64-setup.exe)
alex-3.1.4.log
GHC runtime linker: fatal error: I found a duplicate definition for symbol
hsprimitive_memcpy
whilst processing object file
C:\Users\xxxxx\AppData\Roaming\stack\snapshots\x86_64-windows\lts-3.8\7.10.2\lib\x86_64-windows-ghc-7.10.2\primitive-0.6.1.0-5Jnw7oEuYtM9dmKXelGXVb\HSprimitive-0.6.1.0-5Jnw7oEuYtM9dmKXelGXVb.o
This could be caused by:
* Loading two different object files which export the same symbol
* Specifying the same object file twice on the GHCi command line
* An incorrect `package.conf' entry, causing some object to be
loaded twice.
ghc: panic! (the 'impossible' happened)
(GHC version 7.10.2 for x86_64-unknown-mingw32):
loadObj "C:\\Users\\xxxxx\\AppData\\Roaming\\stack\\snapshots\\x86_64-windows\\lts-3.8\\7.10.2\\lib\\x86_64-windows-ghc-7.10.2\\primitive-0.6.1.0-5Jnw7oEuYtM9dmKXelGXVb\\HSprimitive-0.6.1.0-5Jnw7oEuYtM9dmKXelGXVb.o": failed
It seems that the cause of the error were the duplicated GHC installation.
Thanks for #Reid comment, I realized that I installed Haskel Platform from exe file before and I also installed GHC through stack by folloing the guide.
I unisatlled GHC of Haskel Platform and executed 'stack setup' command.
Then, I executed 'stack build' command and it seemed worked.
I still have problems with the 'stack build' command, but I solved this issue.

Persistent modules not found

I'm trying to use http://hackage.haskell.org/package/persistent-1.2.3.0, but after installing it through "cabal install persistent", ghc doesn't find its exposed-modules:
Prelude> import Database.Persist.Types
<no location info>:
Could not find module `Database.Persist.Types'
It is not a module in the current program, or in any known package.
And ghc-pkg works fine:
$ ghc-pkg find-module Database.Persist.Types
/var/lib/ghc/package.conf.d
/home/apsk/.ghc/x86_64-linux-7.6.3/package.conf.d
persistent-1.2.3.0
Am I missing something or is this just a bug with cabal/persistent/ghc? My ghc is 7.6.3, btw.
Also, I've tried with no effect: "ghc-pkg recache"; "ghc-pkg check"; installing previous version; reinstalling with and without "sudo" and/or "--global".
Check that you're not using sandboxes, cabal-dev, hsenv, anything else that can influence ghc in looking for dependencies. Make sure you're using ghc/ghci, and not any wrappers, and that ghc/ghci are not aliased to anything in your shell.
Try to specify the package-db explicitly:
ghci -package-db /home/apsk/.ghc/x86_64-linux-7.6.3/package.conf.d
If you launch ghci with -v, it'll print the (caches of) databases it looks at, like this:
% ghci -v
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help
Glasgow Haskell Compiler, Version 7.6.3, stage 2 booted by GHC version 7.4.2
Using binary package database: /opt/ghc763/lib/ghc-7.6.3/package.conf.d/package.cache
Using binary package database: /home/feuerbach/.ghc/i386-linux-7.6.3/package.conf.d/package.cache
Make sure that the database which has persistent is listed there.
Hopefully helpful to someone. Using ghci -v I looked to see if persistent was there, and saw this:
package persistent-2.0.8-cec952b1a61645f47dbec3b0b0cbcef4 is unusable due to missing or recursive dependencies: aeson-0.8.0.0-1bd8b5254a1dd30c0fe6acc346ad7de7 attoparsec-0.12.1.2-48393fcdbcf426085b696dc4409d9270 conduit-1.2.0.2-39f9cd0430ed7b7f4306899cbeb1ed83 monad-logger-0.3.7.2-3e6a80e9b3adf31497ff04514bdf2919 resource-pool-0.2.3.0-c02186641e7173f72887d5e65a646ac1 scientific-0.3.3.1-13e0eefbd7215e4503420c3d0a6fdb82 unordered-containers-0.2.5.0-147c3bb8f4a2da7d753455e75af30b92
So I looked around on SO (saw this: Haskell Cabal: Mysterious missing or recursive dependencies) but didn't find a great answer. I did find a good one here though:
$ ghc-pkg list Cabal
Which revealed I had 2 goddamn cabals! One in user and one in global. Ugh. So I was able to do ghc-pkg unregister --user Cabal-1.18.1.3 --force to get rid of the old one. Then cabal install cabal automatically went for 1.20, implicitly into user without any flag (the alternate would be --global).
The problem only occurs in GHCi, right? Have you restarted GHCi since installing persistent? (Maybe there's another way to get GHCi to pick up newly installed packages, but I'm not aware of it.

Haskell doctest and FFI

I have a module which binds to a C function using the FFI. How can I make this module use doctest?
The error I get when running doctest Foo.hs is something like this:
ByteCodeLink: can't find label
During interactive linking, GHCi couldn't find the following symbol:
bar
This may be due to you not asking GHCi to load extra object files,
archives or DLLs needed by your current session. Restart GHCi, specifying
the missing library using the -L/path/to/object/dir and -lmissinglibname
flags, or simply by naming the relevant files on the GHCi command line.
Alternatively, this link failure might indicate a bug in GHCi.
If you suspect the latter, please send a bug report to:
glasgow-haskell-bugs#haskell.org
### Failure in Foo.hs:41: expression `foo'
expected: [42]
but got:
<interactive>:24:1: Not in scope: `bar'
Examples: 2 Tried: 2 Errors: 0 Failures: 1
Doctest accepts arbitrary GHC flags. If you want to run Doctest with FFI code you need to pass the exact same flags that you would need to run a GHCi session with that code. Have e.g. a look at the Doctest driver of unix-time.

Resources