[Rcpp-devel] Segfault, is it because of iterators/pointers?

Alessandro Mammana mammana at molgen.mpg.de
Wed Feb 12 11:47:22 CET 2014


Ok I was able to find the code causing the bug. So it looks like the
pointers you get from an Rcpp::Vector using .begin() become invalid
after that the Rcpp::Vector goes out of scope (and this makes sense),
what I do not understand is that this Rcpp::Vector was allocated in R
and should still be "living" during the execution of the Rcpp call
(that's why I wasn't expecting the pointer to be invalid).

This is the exact code (the one above is probably fine):
@@@@@@@@@@@@@@ in CPP @@@@@@@@@@@@@@i

struct GapMat {
    int* ptr;
    int* colset;
    int nrow;
    int ncol;


    inline int* colptr(int col){
        return ptr + colset[col];
    }

    GapMat(){}

    GapMat(int* _ptr, int* _colset, int _nrow, int _ncol):
        ptr(_ptr), colset(_colset), nrow(_nrow), ncol(_ncol){}
};


GapMat getGapMat(Rcpp::List gapmat){
    IntegerVector vec = gapmat["vec"];
    IntegerVector pos = gapmat["colset"];
    int nrow = gapmat["nrow"];

    return GapMat(vec.begin(), pos.begin(), nrow, pos.length());
}

// [[Rcpp::export]]
IntegerVector colSumsGapMat(Rcpp::List gapmat){

    GapMat mat = getGapMat(gapmat);
    IntegerVector res(mat.ncol);

    for (int i = 0; i < mat.ncol; ++i){
        for (int j = 0; j < mat.nrow; ++j){
            res[i] += mat.colptr(i)[j];
        }
    }

    return res;
}

@@@@@@@@@@@@@@ in R (with gdb debugger as suggested by Dirk) @@@@@@@@@@@@@@i
library(Rcpp)
sourceCpp("scratchpad.cpp")

vec <- rnbinom(3e7, mu=0.1, size=1); storage.mode(vec) <- "integer"
nr <- 80

colset <- sample(3e7-nr, 1e7)
foo <- vec[colset] #this is only to trigger some obscure garbage
collection mechanisms...

for (i in 1:10){
    colset <- sample(3e7-nr, 1e7)
    gapmat <- list(vec=vec, nrow=nr, colset=colset-1)
    cs <- colSumsGapMat(gapmat)
    print(sum(cs))
}

[1] 80000000
[1] 80000000
[1] 80016890
[1] 80008144
[1] 80016022
[1] 80021609

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff18a5455 in GapMat::colptr (this=0x7fffffffc120, col=0) at
scratchpad.cpp:295
295            return ptr + colset[col];

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

Why did it happen? What should I do to make sure that my pointers
remain valid? My goal is to convert safely some vectors or matrices
that "exist" in R to some pointers, how can I do that?

Thanks a lot for your help

Ale

On Tue, Feb 11, 2014 at 3:44 PM, Dirk Eddelbuettel <edd at debian.org> wrote:
>
> In essence: "Yes"
>
> On 11 February 2014 at 15:18, Alessandro Mammana wrote:
> | Hi all,
> | I got another segfault using Rcpp. It is very difficult to understand
> | where it happens and to reduce it to a minimal example, so for now I
> | am not posting very precise code here, but I have a suspicion, maybe
> | you could help me saying if my suspect is right.
>
> Use a debugger:
>
>     R -d gdb
>
> and then proceed as normal.
>
> Make sure your compiler flags include -g as well.
>
> Dirk
>
>
> | I am doing something similar:
> |
> | in a .cpp file:
> | @@@@@@@@@@@@@@@@@@@
> | struct GapMat {
> |     int* ptr;
> |     int* colset;
> |     int nrow;
> |     int ncol;
> |
> |
> |     inline int* colptr(int col){
> |         return ptr + colset[col];
> |     }
> |
> |     GapMat(){}
> |
> |     GapMat(int* _ptr, int* _colset, int _nrow, int _ncol):
> |         ptr(_ptr), colset(_colset), nrow(_nrow), ncol(_ncol){}
> | };
> |
> |
> | // [[Rcpp::export]]
> | IntegerVector colSumsGapMat(Rcpp::IntegerVector vec,
> | Rcpp::IntegerVector pos, int nrow){
> |    GapMat mat(vec.begin(), pos.begin(), nrow, pos.length());
> |    IntegerVector res(pos.length());
> |
> |     for (int i = 0; i < pos.length(); ++i){
> |         for (int j = 0; j < nrow; ++j){
> |             res[i] += mat.colptr(i)[j];
> |         }
> |     }
> |
> |     return res;
> | }
> | @@@@@@@@@@@@@@@@@@@@@
> |
> | from R:
> |
> | vec <- a very big integer vector
> | nrow <- 80
> | pos <- a very big subset of positions, such that max(pos) + nrow < length(vec)
> | colsums <- colSumsGapMat(vec, pos, nrow)
> |
> |
> | from time to time I get a segfault.
> | Note: this is not exactly the code that produces the segfault (because
> | that one is very complicated), so it might be that this code is
> | totally fine.
> |
> | My suspicion:
> |
> | I am using the pointer "vec.begin()", but then I am allocating new
> | memory in the R area of memory with "IntegerVector res(pos.length())"
> | and R decides to move the original values of "vec" to some other
> | place, making the pointer invalid.
> |
> | Is that possible????
> |
> | Sorry for being very vague and thx in advance!!!
> | Ale
> |
> | --
> | Alessandro Mammana, PhD Student
> | Max Planck Institute for Molecular Genetics
> | Ihnestraße 63-73
> | D-14195 Berlin, Germany
> | _______________________________________________
> | Rcpp-devel mailing list
> | Rcpp-devel at lists.r-forge.r-project.org
> | https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
>
> --
> Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com



-- 
Alessandro Mammana, PhD Student
Max Planck Institute for Molecular Genetics
Ihnestraße 63-73
D-14195 Berlin, Germany


More information about the Rcpp-devel mailing list