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 <
[email protected]> 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/598ff7841e5e155c1fff89bf75cd2a91ee7796e2/mlsource/extra/CInterface/Examples/NewForeignTest.sml
>> 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
>> [email protected]
>> http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
>>
>> _______________________________________________
> polyml mailing list
> [email protected]
> http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
>
_______________________________________________
polyml mailing list
[email protected]
http://lists.inf.ed.ac.uk/mailman/listinfo/polyml