Skip to content

[Rcpp-devel] Rcpp example that crashes on 64 bit Windows

10 messages · Dirk Eddelbuettel, Rajen Shah, William Dunlap

#
Hello,

I am having trouble debugging a package that appears to work fine on Mac
operating systems but crashes on Unix and Windows.

I have found the following example that crashes on my Windows setup
(session info copied below)

IntegerVector runif_int2() {
  return wrap(floor(runif(1000000)));
}

When this is called about 5-10 times in succession R crashes (e.g. with
set.seed(1), but this doesn't seem to matter).

Any ideas about why this crashes would be much appreciated. To be clear, I
am not looking for an alternative to the above code (which simply produces
a vector of zeroes), but would like to know what aspects of this cause a
crash so I know what code structures may be causing problems in the package
I am creating. The code does not appear to crash on Mac and I have yet to
try it on Unix.

Many thanks in advance,

Rajen

Session info:

R version 3.3.1 (2016-06-21)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United
States.1252    LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                           LC_TIME=English_United
States.1252

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

loaded via a namespace (and not attached):
[1] tools_3.3.1
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20160811/6cdb8ac5/attachment.html>
#
On 11 August 2016 at 06:28, Rajen Shah wrote:
| Hello,
| 
| I am having trouble debugging a package that appears to work fine on Mac
| operating systems but crashes on Unix and Windows.
| 
| I have found the following example that crashes on my Windows setup (session
| info copied below)
| 
| IntegerVector runif_int2() {
| ? return wrap(floor(runif(1000000)));
| }
| 
| When this is called about 5-10 times in succession R crashes (e.g. with
| set.seed(1), but this doesn't seem to matter).
| 
| Any ideas about why this crashes would be much appreciated. To be clear, I am
| not looking for an alternative to the above code (which simply produces a
| vector of zeroes), but would like to know what aspects of this cause a crash so
| I know what code structures may be causing problems in the package I am
| creating. The code does not appear to crash on Mac and I have yet to try it on
| Unix.

i)  On my box it doesn't run (which is probably a bug)

R> library(Rcpp)
R> cppFunction("IntegerVector runif_int2() { return wrap(floor(runif(1000000))); }")
R> set.seed(1)
R> replicate(100, runif_int2())   ## should probably use loop here...
Error in runif_int2() : unimplemented type 'integer' in 'coerceToInteger'
R> 

ii) Your code is still "wrong" or less than ideal. You really are working
with doubles there, even after the floor() around runif.  So maybe return a
double vector?  Else assign explictly via a cast.

Dirk




| 
| Many thanks in advance,
| 
| Rajen
| 
| Session info:
| 
| R version 3.3.1 (2016-06-21)
| Platform: x86_64-w64-mingw32/x64 (64-bit)
| Running under: Windows >= 8 x64 (build 9200)
| 
| locale:
| [1] LC_COLLATE=English_United States.1252 ?LC_CTYPE=English_United States.1252
| ? ?LC_MONETARY=English_United States.1252
| [4] LC_NUMERIC=C ? ? ? ? ? ? ? ? ? ? ? ? ? LC_TIME=English_United States.1252 ?
| ?
| 
| attached base packages:
| [1] stats ? ? graphics ?grDevices utils ? ? datasets ?methods ? base ? ??
| 
| loaded via a namespace (and not attached):
| [1] tools_3.3.1
| _______________________________________________
| Rcpp-devel mailing list
| Rcpp-devel at lists.r-forge.r-project.org
| https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
#
Dear Dirk,

Many thanks. So I'm concluding that wrap is not meant to do casting in this
sense but rather converts non-SEXP to SEXP, and so crashing is not
unexpected.

Best,

Rajen
On 11 August 2016 at 07:43, Dirk Eddelbuettel <edd at debian.org> wrote:

            
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20160811/d4129a74/attachment.html>
#
Using 'valgrind', along with gctorture(TRUE) can help track down these
bugs. E.g.

% R --debugger valgrind
==8445== Memcheck, a memory error detector
==8445== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==8445== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==8445== Command: /home/R/R-3.3.1/lib/R/bin/exec/R
... bunch of warnings from dl-load, etc., at startup ...
wrap(floor(runif(1000000))); }")
==8445== Invalid read of size 8
==8445==    at 0x4ED9465: Rf_coerceVector (coerce.c:495)
==8445==    by 0x100A3191: SEXPREC*
Rcpp::internal::basic_cast<13>(SEXPREC*) (r_cast.h:58)
==8445==    by 0x100A1AD7: runif_int2() (r_cast.h:67)
==8445==    by 0x100A1F85: sourceCpp_1_runif_int2 (file20fd25662b99.cpp:16)
==8445==    by 0x4F0BD17: do_dotcall (dotcode.c:1251)
==8445==    by 0x4F4C2BA: Rf_eval (eval.c:713)
==8445==    by 0x4F4D646: Rf_applyClosure (eval.c:1134)
==8445==    by 0x4F4BE9E: Rf_eval (eval.c:732)
==8445==    by 0x4F4F68D: do_set (eval.c:2196)
==8445==    by 0x4F4C0C2: Rf_eval (eval.c:685)
==8445==    by 0x4F730E1: Rf_ReplIteration (main.c:258)
==8445==    by 0x4F73430: R_ReplConsole (main.c:308)
==8445==  Address 0x115ea048 is not stack'd, malloc'd or (recently) free'd
==8445==

 *** caught segfault ***
address 0x115ea048, cause 'memory not mapped'

Traceback:
 1: .Primitive(".Call")(<pointer: 0x100a1f40>)
 2: runif_int2()

Possible actions:
1: abort (with core dump, if enabled)
2: normal R exit
3: exit R without saving workspace
4: exit R saving workspace
Selection: 3
==8445==
==8445== HEAP SUMMARY:
==8445==     in use at exit: 48,075,889 bytes in 14,975 blocks
==8445==   total heap usage: 64,852 allocs, 49,877 frees, 107,416,930 bytes
allocated
==8445==
==8445== LEAK SUMMARY:
==8445==    definitely lost: 0 bytes in 0 blocks
==8445==    indirectly lost: 0 bytes in 0 blocks
==8445==      possibly lost: 0 bytes in 0 blocks
==8445==    still reachable: 48,075,889 bytes in 14,975 blocks
==8445==         suppressed: 0 bytes in 0 blocks
==8445== Rerun with --leak-check=full to see details of leaked memory



Bill Dunlap
TIBCO Software
wdunlap tibco.com
On Thu, Aug 11, 2016 at 4:28 AM, Rajen Shah <rds37 at cam.ac.uk> wrote:

            
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20160811/a407467b/attachment-0001.html>
#
To follow-up, if we avoid the cast this works just find as you'd expect:

R> cppFunction("NumericVector myrunif() { return floor(runif(1000000)); }")
R> for (i in 1:100) ignoreme <- myrunif()
R> 

Dirk
#
Many thanks Bill and Dirk.

I'm now explicitly casting each element and this works fine. I was just
surprised that this inappropriate use of wrap would cause a memory leak on
certain OS's and run without problems on others.

Best wishes,

Rajen
On 11 August 2016 at 10:18, Dirk Eddelbuettel <edd at debian.org> wrote:

            
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20160811/2178a94c/attachment.html>
#
Have you tried running your code on the Mac after setting gctorture(TRUE)?

By the way, valgrind showed the opposite of a memory leak - the code was
using memory that it had declared free.  A leak is when the code does not
free memory that it can no longer use.

Bill Dunlap
TIBCO Software
wdunlap tibco.com
On Thu, Aug 11, 2016 at 8:28 AM, Rajen Shah <rds37 at cam.ac.uk> wrote:

            
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20160811/dca101dd/attachment.html>
#
No I have not tried this (and no longer have the Mac available
unfortunately). I have a very limited understanding of memory management,
but I guess you're suggesting setting this to TRUE would make sure that
freed memory really is free, and so would help uncover an issue where the
code tries to use memory that it has declared free?
using memory that it had declared free.  A leak is when the code does not
free memory that it can no longer use.

I am unfamiliar with how to interpret valgrid output, but are you deducing
this from "allocs > frees"?

Thanks: a useful way of finding the most horrible memory issue bugs it
seems.

Rajen
On 11 August 2016 at 10:33, William Dunlap <wdunlap at tibco.com> wrote:

            
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20160811/7f4b6fb5/attachment.html>
#
I realise there is a helpful section on this in

https://cran.r-project.org/doc/manuals/r-release/R-exts.html#Checking-memory-access

which I'm now reading.

Thanks for your help.

Best,

Rajen
On 11 August 2016 at 10:45, Rajen Shah <rds37 at cam.ac.uk> wrote:

            
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20160811/e2fbdcab/attachment-0001.html>
#
On 11 August 2016 at 11:05, Rajen Shah wrote:
| I realise there is a helpful section on this in
| 
| https://cran.r-project.org/doc/manuals/r-release/R-exts.html#
| Checking-memory-access
| 
| which I'm now reading.

We generally shield you from this.  That is, you create objects without
having to worry about.  But a) casts (particularly implicit ones) and b) the
wrap() return business are really complicated.

If you err on the side of caution everything works:

R> cppFunction("IntegerVector myrunif() { NumericVector x = floor(runif(1000000)); return as<IntegerVector>(x); }")
R> for (i in 1:100) ignoreme <- myrunif()
R> 

Here we start with the numeric vector, then cast to an integer vector which
is what is returned.

Dirk