Hi, I am also finding that code segfaults when the ffi functions are used in a loop. For example in the following I create a large array, and I can easily set and then get the 1000th element (compile code below without "val () = loop (pData);" in the main function). However when the ffi functions are used in a loop, the code segfaults around setting and getting the 78th element. The code is messy & I dont properly deallocate the array, but it is just for illustration. The instructions I am using to create the shared library are at the top of the c file.
************************************************************ //gcc -c -fPIC intArray.c //gcc -shared -o intArray.so intArray.o //intArray.c #include <stdlib.h> #include <stdio.h>
typedef struct _intArray { int size; int* arr; } intArray;
intArray* createIntArray(int size){ printf("size = %d\n",size); int i; intArray* p = (intArray*) malloc (sizeof(intArray)); p->arr = (int*) malloc (size*sizeof(int)); for(i=0; i<size; i++){ p->arr[i] = 0; } p->size = size; return p; }
int getIntArray(intArray *p, int elem){ printf("get elem = %d\n",elem); return p->arr[elem]; }
void setIntArray(intArray* p, int elem, int val){ printf("set elem = %d\n",elem); p->arr[elem] = val; }
************************************************************
open Foreign;
val mylib = loadLibrary "./intArray.so";
val c1 = call1 (getSymbol mylib "createIntArray") cInt cPointer val c3 = call3 (getSymbol mylib "setIntArray") (cPointer,cInt,cInt) cVoid val c4 = call2 (getSymbol mylib "getIntArray") (cPointer,cInt) cInt
fun c_createIntArray (size) = c1 (size); fun c_getIntArray (p,elem) = c4 (p,elem); fun c_setIntArray (p,elem,value) = c3 (p,elem,value);
val size:int = 50000; val loops:int = 30; val cap:int = 50000;
fun loop (pData2) = let fun loopI i = if i = size then let val _ = () in c_setIntArray(pData2,0,c_getIntArray(pData2,size-1)); () end else let val previous = c_getIntArray(pData2,i-1); val previous = 0; val use = if previous > cap then 0 else previous in c_setIntArray(pData2,i,use+1); loopI (i+1) end in loopI 1 end
fun main () = let val pData = c_createIntArray(size); val () = c_setIntArray(pData,1000,123); val () = loop (pData); (* <-- THIS CAUSES SEGFAULT*) val element = c_getIntArray(pData,1000); in print (Int.toString element) end
************************************************************
On Sat, Oct 10, 2015 at 9:19 AM, David Matthews < David.Matthews at prolingua.co.uk> wrote:
That was quick! I only merged it about an hour ago. Basically the idea is that the loading of the library and extracting the symbol is deferred until the function is called. That allows functions to be defined in one session, saved with PolyML.export or PolyML.SaveState.saveState and then used in a subsequent session, even if the library is not actually available at the time of definition.
What seems to be happening here is that the exception that should be raised is getting handled at the wrong place. I need to look at it.
David
On 10/10/2015 08:56, Artella Coding wrote:
Hi, I was trying out the new foreign function interface that was committed today, and I find that if one tries to load a symbol that does not exist no error message is returned. For example in
https://github.com/polyml/polyml/blob/598ff7841e5e155c1fff89bf75cd2a91ee7796... if I do
val sumTree2 = call1 ( getSymbol mylib "SumTreeDoesNotExist" ) cTree cInt;
then no error message is reported. Then upon the call to
sumTree aTree;
an error is encountered and the program just terminates.
Thanks
polyml mailing list polyml at inf.ed.ac.uk http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
polyml mailing list polyml at inf.ed.ac.uk http://lists.inf.ed.ac.uk/mailman/listinfo/polyml