I'm trying to interact with a Basler USB3 camera from a Haskell app, but I'm having some difficulties. The camera is equipped with a C ++ library, which makes it quite simple. To get the camera source, you can use the following code:
extern "C" { void basler_init() { PylonAutoInitTerm pylon; CInstantCamera camera( CTlFactory::GetInstance().CreateFirstDevice()); camera.RegisterConfiguration( (CConfigurationEventHandler*) NULL, RegistrationMode_ReplaceAll, Cleanup_None); cout << "Using device " << camera.GetDeviceInfo().GetModelName() << endl; } }
I used this source code to create a shared library - libbasler.so . To confirm that this works, here is a basic C program that references it and confirms that everything works:
void basler_init(); int main () { basler_init(); }
I compile and run this as:
$ gcc Test2.c -lbasler -Llib -Wl,--enable-new-dtags -Wl,-rpath,pylon5/lib64 -Wl,-E -lpylonbase -o Test2-c $ PYLON_CAMEMU=1 LD_LIBRARY_PATH=lib ./Test2-c Using device Emulation
This is the expected result.
However, when I try to use this with Haskell, the behavior changes and the program blocks indefinitely. Here is the source code for Haskell:
{-# LANGUAGE ForeignFunctionInterface #-} foreign import ccall "basler_init" baslerInit :: IO () main :: IO () main = baslerInit
I compile and run this as:
$ ghc --make Test2.hs -o Test2-haskell -Llib -lbasler -optl-Wl,--enable-new-dtags -optl-Wl,-rpath,pylon5/lib64 -optl-Wl,-E -lpylonbase $ PYLON_CAMEMU=1 LD_LIBRARY_PATH=lib ./Test2-haskell
The application now freezes indefinitely.
I went through strace to try to get an idea of ββwhat was going on, but I cannot interpret it. The output is too long to add here, but please look at these two pastes:
Also, I used gdb to try to figure out where the Haskell application is stuck:
$ PYLON_CAMEMU=1 LD_LIBRARY_PATH=lib gdb Test2-haskell GNU gdb (GDB) 7.11 Copyright (C) 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http:
For program C:
Reading symbols from Test2-c...done. (gdb) run Starting program: /home/ollie/work/circuithub/receiving-station/Test2-c warning: File "/nix/store/9ljgbhb26ca0j9shwh8bwsa77h42izr2-gcc-5.4.0-lib/lib/libstdc++.so.6.0.21-gdb.py" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load". To enable execution of this file add add-auto-load-safe-path /nix/store/9ljgbhb26ca0j9shwh8bwsa77h42izr2-gcc-5.4.0-lib/lib/libstdc++.so.6.0.21-gdb.py line to your configuration file "/home/ollie/.gdbinit". To completely disable this security protection add set auto-load safe-path / line to your configuration file "/home/ollie/.gdbinit". For more information about this security protection see the "Auto-loading safe path" section in the GDB manual. Eg, run from the shell: info "(gdb)Auto-loading safe path" [Thread debugging using libthread_db enabled] Using host libthread_db library "/nix/store/bb32xf954imhdrzn7j8h82xs1bx7p3fr-glibc-2.23/lib/libthread_db.so.1". [New Thread 0x7fffed4ae700 (LWP 13792)] [New Thread 0x7fffeccad700 (LWP 13793)] Using device Emulation [Thread 0x7fffeccad700 (LWP 13793) exited] [Thread 0x7fffed4ae700 (LWP 13792) exited] [Inferior 1 (process 13788) exited normally]
My guess is that the GHC runtime does something that causes pthreads to have different behavior, but I'm not sure what it might be.