[R-pkg-devel] Failing Valgrind Passing R CMD check
Duncan Murdoch
murdoch@dunc@n @end|ng |rom gm@||@com
Sun Mar 6 21:00:50 CET 2022
On 06/03/2022 12:00 p.m., Dirk Eddelbuettel wrote:
>
> R CMD check --use-valgrind is a very useful option. But I am puzzled by the
> fact that we have code that is clearly incorrect, detected by valgrind, yet
> given a pass by R CMD check.
>
> A tiny demo package is at https://github.com/eddelbuettel/demovalgrindnonfail
>
> Its sole C function (included below in [1]) copies a vector by allocating --
> and not releasing. Valgrind sees that: in tests/ we pass a numeric vector of
> four so we get 'definitely lost: 32 bytes in 1 blocks' (see [2]). Yet R CMD
> check is happy as a clam (see [3]).
>
> Is that a bug? Should we extend package tools to error here?
>
> Dirk
>
>
>
> [1] C function which allocates but does not release
>
> SEXP simpleCall_impl(SEXP x) {
> int n = Rf_length(x);
> int m = n * sizeof(double);
>
> double* srcptr = REAL(x);
> double* dstptr = malloc(m); // allocate, never release --> leak
> memcpy((void*)dstptr, (void*)srcptr, m); // so compiler does not complain about unused ptr
>
> Rprintf("n=%d x[1]=%f\n", n, (double) dstptr[1]);
> return R_NilValue;
> }
>
>
> [2] Valgrind summary with as-expected finding
>
> ==1485886== HEAP SUMMARY:
> ==1485886== in use at exit: 53,538,524 bytes in 10,178 blocks
> ==1485886== total heap usage: 27,543 allocs, 17,365 frees, 87,496,835 bytes allocated
> ==1485886==
> ==1485886== LEAK SUMMARY:
> ==1485886== definitely lost: 32 bytes in 1 blocks
> ==1485886== indirectly lost: 0 bytes in 0 blocks
> ==1485886== possibly lost: 0 bytes in 0 blocks
> ==1485886== still reachable: 53,538,492 bytes in 10,177 blocks
> ==1485886== suppressed: 0 bytes in 0 blocks
> ==1485886== Rerun with --leak-check=full to see details of leaked memory
> ==1485886==
> ==1485886== For lists of detected and suppressed errors, rerun with: -s
> ==1485886== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
>
>
> [3] R CMD check, with valgrind and its error detection
>
> edd using rob:~/git/demovalgrindnonfail(master)$ R CMD check --use-valgrind demovalgrindnonfail_0.0.1.tar.gz
> * using log directory ‘/home/edd/git/demovalgrindnonfail/demovalgrindnonfail.Rcheck’
> * using R version 4.1.2 (2021-11-01)
> * using platform: x86_64-pc-linux-gnu (64-bit)
> * using session charset: UTF-8
> * using option ‘--use-valgrind’
> * checking for file ‘demovalgrindnonfail/DESCRIPTION’ ... OK
> * checking extension type ... Package
> * this is package ‘demovalgrindnonfail’ version ‘0.0.1’
> * checking package namespace information ... OK
> * checking package dependencies ... OK
> * checking if this is a source package ... OK
> * checking if there is a namespace ... OK
> * checking for executable files ... OK
> * checking for hidden files and directories ... OK
> * checking for portable file names ... OK
> * checking for sufficient/correct file permissions ... OK
> * checking whether package ‘demovalgrindnonfail’ can be installed ... OK
> * checking installed package size ... OK
> * checking package directory ... OK
> * checking DESCRIPTION meta-information ... OK
> * checking top-level files ... OK
> * checking for left-over files ... OK
> * checking index information ... OK
> * checking package subdirectories ... OK
> * checking R files for non-ASCII characters ... OK
> * checking R files for syntax errors ... OK
> * checking whether the package can be loaded ... OK
> * checking whether the package can be loaded with stated dependencies ... OK
> * checking whether the package can be unloaded cleanly ... OK
> * checking whether the namespace can be loaded with stated dependencies ... OK
> * checking whether the namespace can be unloaded cleanly ... OK
> * checking loading without being on the library search path ... OK
> * checking dependencies in R code ... OK
> * checking S3 generic/method consistency ... OK
> * checking replacement functions ... OK
> * checking foreign function calls ... OK
> * checking R code for possible problems ... OK
> * checking Rd files ... OK
> * checking Rd metadata ... OK
> * checking Rd cross-references ... OK
> * checking for missing documentation entries ... OK
> * checking for code/documentation mismatches ... OK
> * checking Rd \usage sections ... OK
> * checking Rd contents ... OK
> * checking for unstated dependencies in examples ... OK
> * checking line endings in C/C++/Fortran sources/headers ... OK
> * checking compilation flags used ... OK
> * checking compiled code ... OK
> * checking examples ... NONE
> * checking for unstated dependencies in ‘tests’ ... OK
> * checking tests ...
> Running ‘simpleCall.R’
> OK
> * checking PDF version of manual ... OK
> * DONE
>
> Status: OK
>
> edd using rob:~/git/demovalgrindnonfail(master)$
>
What does simpleCall.R do? If it only calls your bad function once, R
might ignore the 32 bytes lost. As WRE says, R itself loses small
amounts of memory: "We know there will be some small memory leaks from
@code{readline} and @R{} itself --- these are memory areas that are in
use right up to the end of the @R{} session. "
I took a quick look but didn't spot where (if?) R analyzes the valgrind
output.
Duncan Murdoch
More information about the R-package-devel
mailing list