[Rd] Writting my own package - 64 bit problem with R_GetCCallable

Ryan King c.ryan.king at gmail.com
Fri Feb 11 22:29:24 CET 2011

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

R_as_cholmod_sparse(CHM_SP ans, SEXP x, Rboolean check_Udiag, Rboolean
    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

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)

 [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

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

More information about the R-devel mailing list