From saptarshi.guha at gmail.com  Mon Sep 21 07:15:23 2009
From: saptarshi.guha at gmail.com (Saptarshi Guha)
Date: Mon, 21 Sep 2009 01:15:23 -0400
Subject: [Rd] Return a list from a .Call but segfaults
In-Reply-To: <1e7471d50909192104w3bdfc108jef4ccada77412675@mail.gmail.com>
References: <3048D5A8-4F01-497B-AED1-21C199D9B448@gmail.com> 
	<1e7471d50909192104w3bdfc108jef4ccada77412675@mail.gmail.com>
Message-ID: <1e7471d50909202215r4408690dr89746f419a7b3813@mail.gmail.com>

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
>>
>>
>>
>



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