[Rd] segfault
Peter Dalgaard BSA
p.dalgaard@pubhealth.ku.dk
22 Feb 2001 23:37:18 +0100
Paul Gilbert <gilb@home.com> writes:
> >The actual bug is probably somewhat prior to this. If you do a "bt"
> >(backtrace) and go "up" a couple of times, you might find a spot where
> >someone forgot to PROTECT() a newly created R object.
>
> Well ddd still does not install the innocent with the knowlege of C
> programmers so I am guessing a bit about exactly what I should be
> looking for. If I do "up" a few times I see a section of main/dotcode.c
> starting at line 180 (copied below) that looks like it might have a
> problem. The first few cases do not have any PROTECT statements and
> others do. If this is not a a good guess then perhaps someone could fill
> me in on what statements that create new R objects look like.
Briefly (and this'll have to be brief or I'll end up writing a
book...) things like allocVector create a new objects. As long as such
an object is "loose" - not assigned to an environment or made part of
an object which is - it is in danger of being destroyed by the garbage
collector. However, the garbage collector is not called randomly, it
can only happen when memory for a new object is being allocated.
In the first handful of cases below, one allocates a vector and stuffs
some preexisting values into it (sitting in iptr, sptr, rptr,....) and
then passes s onto something else (it is the return value of
CPtrToRObj and that only gets called from do_dotCode where the return
value gets protected eventually)
However, in the STRSXP case, s needs protection because of the
mkChar(buf) which will allocate memory, and hence the construction:
PROTECT(s = allocVector(type, 1));
SET_STRING_ELT(s, 0, mkChar(buf));
UNPROTECT(1);
I don't think this stretch of code is the culprit - it is a far too
busy area to be likely to have major bugs of this caliber.
Actually, once do_dotCode is involved, I'd suspect array overruns
rather than PROTECT bugs. I've seen several cases where a vector
turned out to getting passed with the wrong length or the wrong type.
Be very careful that all arguments to .Fortran/.C are explicitly
coerced to the right type - if you forget an as.double you might get a
routine that works impeccably until someone passes something like 1:12
(which has storage mode "integer") as an argument.
> Thanks,
> Paul
> _____
> case INTSXP:
> s = allocVector(type, n);
> iptr = (int*)p;
> for(i=0 ; i<n ; i++) {
> INTEGER(s)[i] = iptr[i];
> }
> break;
> case REALSXP:
> s = allocVector(type, n);
> if(asLogical(getAttrib(arg, CSingSymbol)) == 1) {
> sptr = (float*) p;
> for(i=0 ; i<n ; i++) REAL(s)[i] = (double) sptr[i];
> } else {
> rptr = (double*) p;
> for(i=0 ; i<n ; i++) REAL(s)[i] = rptr[i];
> }
> break;
> case CPLXSXP:
> s = allocVector(type, n);
> zptr = (Rcomplex*)p;
> for(i=0 ; i<n ; i++) {
> COMPLEX(s)[i] = zptr[i];
> }
> break;
> case STRSXP:
> if(Fort) {
> /* only return one string: warned on the R -> Fortran step */
> strncpy(buf, (char*)p, 255);
> buf[256] = '\0';
> PROTECT(s = allocVector(type, 1));
> SET_STRING_ELT(s, 0, mkChar(buf));
> UNPROTECT(1);
> } else ...
>
>
--
O__ ---- Peter Dalgaard Blegdamsvej 3
c/ /'_ --- Dept. of Biostatistics 2200 Cph. N
(*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918
~~~~~~~~~~ - (p.dalgaard@biostat.ku.dk) FAX: (+45) 35327907
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._