Skip to content

segfault

2 messages · Paul Gilbert, Peter Dalgaard

#
A few people suggested ddd might be preferred to xxgdb, where upon xxgdb
crashed on me. I have now managed to get ddd working on my linux box at
home, but am still having some difficulty at work. (It requires a newer
c++ ,  some *tif libraries, etc.)

---- Peter D.  writes:
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.

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

-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
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
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._
#
Paul Gilbert <gilb@home.com> writes:
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.