[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