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

Ryan King c.ryan.king at gmail.com
Fri Feb 11 23:03:17 CET 2011


Ah thanks, that did fix it.

Ryan King

On Fri, Feb 11, 2011 at 3:53 PM, Simon Urbanek
<simon.urbanek at r-project.org> wrote:
> 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