[Rd] Return a list from a .Call but segfaults
Saptarshi Guha
saptarshi.guha at gmail.com
Mon Sep 21 07:15:23 CEST 2009
Apparantly , calling Rf_duplicate on the return value message2rexp solves it.
Regards
Saptarshi
On Sun, Sep 20, 2009 at 12:04 AM, Saptarshi Guha
<saptarshi.guha at gmail.com> wrote:
> After some examination, this is what i found (i changed the code
> somewhat, i dont modify rawdata anymore)
>
> load("/tmp/v.Rdata")
> dyn.load("/ln/meraki/custom/lib64/R/library/mylib/libs/lib.so")
> v=.Call("returnListOfKV",rawkv,numread)
>
> ## v is a list of 28231 lists each of length 2
> j=v[1:10000] ; u=list();u=append(u,j)
> and
> j=v[1:15164] ; u=list();u=append(u,j)
> both work but for n> 15164
> j=v[1:n] ; u=list();u=append(u,j)
> returns
> Error: protect(): protection stack overflow
>
> I have no idea why...
> Regards
> Saptarshi
>
>
>
>
> On Sat, Sep 19, 2009 at 10:15 PM, Saptarshi Guha
> <saptarshi.guha at gmail.com> wrote:
>> 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