[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