[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