From saptarshi.guha at gmail.com  Sun Sep 20 04:15:30 2009
From: saptarshi.guha at gmail.com (Saptarshi Guha)
Date: Sat, 19 Sep 2009 22:15:30 -0400
Subject: [Rd] Return a list from a .Call but segfaults
Message-ID: <3048D5A8-4F01-497B-AED1-21C199D9B448@gmail.com>

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



[Rd] Return a list from a .Call but segfaults
Saptarshi Guha