Ryan King
2011-Feb-11 21:29 UTC
[Rd] Writting my own package - 64 bit problem with R_GetCCallable
Hello list, I've been working on a package of my own. It works fine on the 32bit linux machines that I've tested it on. Someone using 64bit ubuntu wanted to try it, and surprising segfaults happened. My test code results in no segfault, errors, or leaks from my calls when run under valgrind (I recompiled R with the level 2 valgrind instruments). R and packages are compiled from source, so this is hopefully not a debian/ubuntu issue. I'm totally stumped and hoping that this is a silly / common 32 to 64 bit transition issue. The problem seems to come when I attempt to access a function registered by the Matrix package. During compilation (on 64 bit only) I get the ominous: -------------- slim_stolen_from_matrix.c: In function ?R_as_cholmod_sparse?: slim_stolen_from_matrix.c:36: warning: implicit declaration of function ?R_GetCCallable? slim_stolen_from_matrix.c:36: warning: cast to pointer from integer of different size -------------- The function in question is an identical copy of Matrix's M_as_cholmod_sparse, reproduced below -------------- CHM_SP R_as_cholmod_sparse(CHM_SP ans, SEXP x, Rboolean check_Udiag, Rboolean sort_in_place) { static CHM_SP(*fun)(CHM_SP,SEXP,Rboolean,Rboolean)= NULL; if(fun == NULL) fun = (CHM_SP(*)(CHM_SP,SEXP,Rboolean,Rboolean)) R_GetCCallable("Matrix", "as_cholmod_sparse"); return fun(ans, x, check_Udiag, sort_in_place); } -------------- I made this duplicate function since using Matrix's #include stubs conflicts with my copy of the CHOLMOD library (I need some functions Matrix doesn't make public). When run, the code gives the following segfault when it reaches te first call to that function: -------------- Program received signal SIGSEGV, Segmentation fault. 0xfffffffff54314e2 in ?? () *** caught segfault *** address 0xfffffffff54314e2, cause 'memory not mapped' -------------- As mentioned above, under valgrind the segault doesn't happen, but in GDB, the function pointer can be seen to have some problem. In 64 bit -------------- 35 fun = (CHM_SP(*)(CHM_SP,SEXP,Rboolean,Rboolean)) (gdb) p fun $1 = (CHM_SP (*)(CHM_SP, SEXP, Rboolean, Rboolean)) 0 (gdb) n 37 return fun(ans, x, check_Udiag, sort_in_place); (gdb) p fun $2 = (CHM_SP (*)(CHM_SP, SEXP, Rboolean, Rboolean)) 0xfffffffff54314e2 -------------- vs 32bit -------------- (gdb) p fun $1 = (CHM_SP (*)(CHM_SP, SEXP, Rboolean, Rboolean)) 0xb72a3ec0 <as_cholmod_sparse> -------------- I've never done 64 bit development, so I don't know what I've probably done wrong. I don't see an intermediate cast to an int to mess it up. Checking the pointer sizeof's seems like R_GetCCallable's return should be the same size as the function pointer. -------------- (gdb) p sizeof(void*) $5 = 8 (gdb) p sizeof(CHM_SP*) $6 = 8 (gdb) p sizeof(CHM_SP) $7 = 8 (gdb) p sizeof(SEXP) $8 = 8 (gdb) p sizeof(CHM_SP(*)) $9 = 8 (gdb) p sizeof(DL_FUNC) $10 = 8 (gdb) p sizeof(DL_FUNC*) $11 = 8 -------------- The function is invoked by ---------- fitholder->Zt = R_as_cholmod_sparse ((CHM_SP)malloc(sizeof(cholmod_sparse)), Zt, TRUE, FALSE); ----------- where Zt is a SEXP pointing to a Matrix-class sparse matrix passed by .Call from R. CHM_SP is a typedef'd pointer to a cholmod_sparse> sessionInfo()R version 2.12.1 (2010-12-16) Platform: x86_64-unknown-linux-gnu (64-bit) locale: [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8 [5] LC_MONETARY=C LC_MESSAGES=en_US.UTF-8 [7] LC_PAPER=en_US.UTF-8 LC_NAME=C [9] LC_ADDRESS=C LC_TELEPHONE=C [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C attached base packages: [1] stats graphics grDevices utils datasets methods base other attached packages: [1] emmpat_0.001 Matrix_0.999375-46 lattice_0.19-13 loaded via a namespace (and not attached): [1] grid_2.12.1 Ryan King University of Chicago Dept. Health Studies
Simon Urbanek
2011-Feb-11 21:53 UTC
[Rd] Writting my own package - 64 bit problem with R_GetCCallable
Ryan, On Feb 11, 2011, at 4:29 PM, Ryan King wrote:> Hello list, > I've been working on a package of my own. It works fine on the 32bit > linux machines that I've tested it on. Someone using 64bit ubuntu > wanted to try it, and surprising segfaults happened. My test code > results in no segfault, errors, or leaks from my calls when run under > valgrind (I recompiled R with the level 2 valgrind instruments). R > and packages are compiled from source, so this is hopefully not a > debian/ubuntu issue. I'm totally stumped and hoping that this is a > silly / common 32 to 64 bit transition issue. > > The problem seems to come when I attempt to access a function > registered by the Matrix package. During compilation (on 64 bit only) > I get the ominous: > > -------------- > slim_stolen_from_matrix.c: In function ?R_as_cholmod_sparse?: > slim_stolen_from_matrix.c:36: warning: implicit declaration of > function ?R_GetCCallable? > slim_stolen_from_matrix.c:36: warning: cast to pointer from integer of > different sizeThis is the key issue - you're missing the declaration of R_GetCCallable() as the compiler tells you, so the compiler assumes "int" as the return value. However, int is only 32-bit so it won't hold a 64-bit pointer and hence you're in trouble. All you really need is #include <R_ext/Rdynload.h> before you use R_GetCCallable and hopefully your issues should go away. Note that your bug is there even in 32-bit -- you will see " implicit declaration of function" in any case -- it just is not fatal, incidentally. It is a good idea to listen to the compiler ... ;). Cheers, Simon> -------------- > > The function in question is an identical copy of Matrix's > M_as_cholmod_sparse, reproduced below > > -------------- > CHM_SP > R_as_cholmod_sparse(CHM_SP ans, SEXP x, Rboolean check_Udiag, Rboolean > sort_in_place) > { > static CHM_SP(*fun)(CHM_SP,SEXP,Rboolean,Rboolean)= NULL; > if(fun == NULL) > fun = (CHM_SP(*)(CHM_SP,SEXP,Rboolean,Rboolean)) > R_GetCCallable("Matrix", "as_cholmod_sparse"); > return fun(ans, x, check_Udiag, sort_in_place); > } > -------------- > > I made this duplicate function since using Matrix's #include stubs > conflicts with my copy of the CHOLMOD library (I need some functions > Matrix doesn't make public). > > When run, the code gives the following segfault when it reaches te > first call to that function: > > -------------- > Program received signal SIGSEGV, Segmentation fault. > 0xfffffffff54314e2 in ?? () > *** caught segfault *** > address 0xfffffffff54314e2, cause 'memory not mapped' > -------------- > > As mentioned above, under valgrind the segault doesn't happen, but in > GDB, the function pointer can be seen to have some problem. In 64 bit > -------------- > 35 fun = (CHM_SP(*)(CHM_SP,SEXP,Rboolean,Rboolean)) > (gdb) p fun > $1 = (CHM_SP (*)(CHM_SP, SEXP, Rboolean, Rboolean)) 0 > (gdb) n > 37 return fun(ans, x, check_Udiag, sort_in_place); > (gdb) p fun > $2 = (CHM_SP (*)(CHM_SP, SEXP, Rboolean, Rboolean)) 0xfffffffff54314e2 > -------------- > > vs 32bit > -------------- > (gdb) p fun > $1 = (CHM_SP (*)(CHM_SP, SEXP, Rboolean, Rboolean)) 0xb72a3ec0 > <as_cholmod_sparse> > -------------- > > I've never done 64 bit development, so I don't know what I've probably > done wrong. I don't see an intermediate cast to an int to mess it up. > Checking the pointer sizeof's seems like R_GetCCallable's return > should be the same size as the function pointer. > > -------------- > (gdb) p sizeof(void*) > $5 = 8 > (gdb) p sizeof(CHM_SP*) > $6 = 8 > (gdb) p sizeof(CHM_SP) > $7 = 8 > (gdb) p sizeof(SEXP) > $8 = 8 > (gdb) p sizeof(CHM_SP(*)) > $9 = 8 > (gdb) p sizeof(DL_FUNC) > $10 = 8 > (gdb) p sizeof(DL_FUNC*) > $11 = 8 > -------------- > > The function is invoked by > ---------- > fitholder->Zt = R_as_cholmod_sparse > ((CHM_SP)malloc(sizeof(cholmod_sparse)), Zt, TRUE, FALSE); > ----------- > > where Zt is a SEXP pointing to a Matrix-class sparse matrix passed by > .Call from R. CHM_SP is a typedef'd pointer to a cholmod_sparse > > > >> sessionInfo() > R version 2.12.1 (2010-12-16) > Platform: x86_64-unknown-linux-gnu (64-bit) > > locale: > [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C > [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8 > [5] LC_MONETARY=C LC_MESSAGES=en_US.UTF-8 > [7] LC_PAPER=en_US.UTF-8 LC_NAME=C > [9] LC_ADDRESS=C LC_TELEPHONE=C > [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C > > attached base packages: > [1] stats graphics grDevices utils datasets methods base > > other attached packages: > [1] emmpat_0.001 Matrix_0.999375-46 lattice_0.19-13 > > loaded via a namespace (and not attached): > [1] grid_2.12.1 > > > Ryan King > University of Chicago > Dept. Health Studies > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > >