I have some strange behavior with GHC 7.6.3 on Ubuntu 14 TLS when using FFI and
I am looking for some ideas on what could be going on.
Fundamentally, adding wait calls (delays coded in the C) changes the behavior
of the C, in that returned status codes have proper values when there are
delays, and return errors when there are no delays. But these same calls result
in proper behavior on the Aardvark’s serial bus, return proper data, etc. Only
the status get’s messed up.
The module calls a thin custom C layer over the Aaardvark C layer, which
dynamically loads a dll and makes calls into it. The thin layer just makes the
use of c2hs eaiser.
It is always possible there is some kind of memory issue, but there is no
pattern to the mishap. It is random. Adding delays just changes probabilities
of bad status.
I made a C version of my application calling the same custom C layer, and there
are no problems. This sort of indicates the problem is with the FFI.
Because the failures are not general in that they target one particular value,
and seem to be affected by time, it makes me wonder if there is some subtle
Haskell run time issue. Like, could the garbage collector be interacting with
things?
Does anyone have an idea what kind of things to look for?
Mike
DLL loader
static void *_loadFunction (const char *name, int *result) {
static DLL_HANDLE handle = 0;
void * function = 0;
/* Load the shared library if necessary */
if (handle == 0) {
u32 (*version) (void);
u16 sw_version;
u16 api_version_req;
_setSearchPath();
handle = dlopen(SO_NAME, RTLD_LAZY);
if (handle == 0) {
#if API_DEBUG
fprintf(stderr, "Unable to load %s\n", SO_NAME);
fprintf(stderr, "%s\n", dlerror());
#endif
*result = API_UNABLE_TO_LOAD_LIBRARY;
return 0;
}
version = (void *)dlsym(handle, "c_version");
if (version == 0) {
#if API_DEBUG
fprintf(stderr, "Unable to bind c_version() in %s\n",
SO_NAME);
fprintf(stderr, "%s\n", dlerror());
#endif
handle = 0;
*result = API_INCOMPATIBLE_LIBRARY;
return 0;
}
sw_version = (u16)((version() >> 0) & 0xffff);
api_version_req = (u16)((version() >> 16) & 0xffff);
if (sw_version < API_REQ_SW_VERSION ||
API_HEADER_VERSION < api_version_req)
{
#if API_DEBUG
fprintf(stderr, "\nIncompatible versions:\n");
fprintf(stderr, " Header version = v%d.%02d ",
(API_HEADER_VERSION >> 8) & 0xff, API_HEADER_VERSION &
0xff);
if (sw_version < API_REQ_SW_VERSION)
fprintf(stderr, "(requires library >= %d.%02d)\n",
(API_REQ_SW_VERSION >> 8) & 0xff,
API_REQ_SW_VERSION & 0xff);
else
fprintf(stderr, "(library version OK)\n");
fprintf(stderr, " Library version = v%d.%02d ",
(sw_version >> 8) & 0xff,
(sw_version >> 0) & 0xff);
if (API_HEADER_VERSION < api_version_req)
fprintf(stderr, "(requires header >= %d.%02d)\n",
(api_version_req >> 8) & 0xff,
(api_version_req >> 0) & 0xff);
else
fprintf(stderr, "(header version OK)\n");
#endif
handle = 0;
*result = API_INCOMPATIBLE_LIBRARY;
return 0;
}
}
/* Bind the requested function in the shared library */
function = (void *)dlsym(handle, name);
*result = function ? API_OK : API_UNABLE_TO_LOAD_FUNCTION;
return function;
}
_______________________________________________
Glasgow-haskell-users mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users