[Rd] Writting my own package - 64 bit problem with R_GetCCallable
Simon Urbanek
simon.urbanek at r-project.org
Fri Feb 11 22:53:26 CET 2011
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 size
This 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
>
>
More information about the R-devel
mailing list