[Rd] Return a list from a .Call but segfaults
Saptarshi Guha
saptarshi.guha at gmail.com
Sun Sep 20 04:15:30 CEST 2009
Hello,
I call a function via .Call passing to it a raw vector(D) and an
integer(I)
The vector is a series K1,KData1, V1,VData1, K2, KData2, ...
where the integer K1 is the length of Data1 and similarly for Ki (wrt
Datai)(similarly for V*) There 2*I such pairs( (Ki,KDatai), (Vi,VDatai))
The numbers Ki(and Vi) are written in network order.
I am returning a list of I elements each element a list of two
elements corresponding to KData and VData (which are serialized R
objects) .
ll <- .Call("returnListOfKV", rawkv, numread)
When use the function with browser(), and type head(ll) i get valid
results.
However, i get a segfault when the code runs the next line
j <- append(j,ll)
(where j was defined as vector(mode='list') )
The code below looks alright, but it appears to crash when getting
copied.
Now one could blame message2rexp (in kk_), but once in R, the result
of .Call is assigned to ll, everything should be protected.
In fact, if in kk_ i simply return a VECSXP with 2 elements, no
errors, so one could conclude that message2rexp is to blame.
Yet, when i replace the code with R code, that is using readBin and
only calling calling C(to call message2rexp) to deserialize a raw
vector, I get no such error.
There is something I'm missing , could someone tell me where?
Thank you for your time
Regards
Saptarshi
=== Using GDB? ====
I would like to run it through gdb, i get the following message
[Thread debugging using libthread_db enabled]
Error while reading shared library symbols:
Cannot find new threads: generic error
Cannot find new threads: generic error]
and cannot proceed.
==== Code ====
SEXP returnListOfKV(SEXP raw,SEXP numread){
if(TYPEOF(raw)!=RAWSXP){
return(R_NilValue);
}
int num = INTEGER(numread)[0];
char *rawdata = (char*)RAW(raw);
SEXP KV ,rval;
int r;
PROTECT(rval = Rf_allocVector(VECSXP, num));
for(int i=0;i<num;i++){
SEXP k = R_NilValue;
PROTECT(KV = Rf_allocVector(VECSXP, 2));
r = reverseUInt(*((int*) rawdata)); //converts network order to
host
rawdata+=4; //yes, hard code size of int
PROTECT(k= kk_(rawdata,r)); //deserializes data and returns a
SEXP
rawdata+= r;
SET_VECTOR_ELT(KV,0, k);
UNPROTECT(1);
r = reverseUInt(*((int*) rawdata));
rawdata+=4;
PROTECT(k= kk_(rawdata,r));
rawdata+=r;
SET_VECTOR_ELT(KV,1, k);
UNPROTECT(1);
SET_VECTOR_ELT(rval,i,KV);
UNPROTECT(1);
}
UNPROTECT(1);
return(rval);
}
SEXP kk_(char *d,int n){
SEXP k;
REXP *rexp = new REXP();
rexp->Clear();
rexp->ParseFromArray(d,n);
PROTECT(k = message2rexp(*rexp));
delete(rexp);
UNPROTECT(1);
return(k);
}
Saptarshi Guha | saptarshi.guha at gmail.com | http://www.stat.purdue.edu/~sguha
More information about the R-devel
mailing list