Skip to content

Commit b3bb03f

Browse files
committed
fix crash on second call to sourceCpp
- Revert previous code which attempted to avoid calling dyn.load on libraries already loaded (which in turn had triggered an R bug that corrupts the load table when this occurs). That code's logic was not correct. - Generate unique shared object paths using a simple static counter rather than a call to sample. The previous issue must have been triggered by sample returning the same integer twice, which in turn may have been triggered by some maniplation of the rng state by expm?.
1 parent 0010c56 commit b3bb03f

File tree

3 files changed

+20
-11
lines changed

3 files changed

+20
-11
lines changed

ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
2015-07-14 JJ Allaire <[email protected]>
2+
3+
* src/attributes.cpp: fix crash on second call to sourceCpp
4+
15
2015-07-07 Matt P. Dziubinski <[email protected]>
26

37
* inst/include/Rcpp/sugar/functions/var.h: Variance -- changed from

inst/NEWS.Rd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
}
1818
\item Changes in Rcpp Attributes:
1919
\itemize{
20-
\item Don't load \code{sourceCpp} dynamic library if it's already
21-
been loaded.
20+
\item Use more robust method of ensuring unique paths for generated shared
21+
libraries.
2222
\item The \code{evalCpp} function now also supports the \code{plugins}
2323
argument.
2424
}

src/attributes.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2813,7 +2813,7 @@ namespace {
28132813
dircreate(buildDirectory_);
28142814

28152815
// generate a random context id
2816-
contextId_ = "sourceCpp_" + createRandomizer();
2816+
contextId_ = "sourceCpp_" + uniqueToken();
28172817

28182818
// regenerate the source code
28192819
regenerateSource();
@@ -2847,7 +2847,7 @@ namespace {
28472847

28482848
// create new dynlib filename
28492849
previousDynlibFilename_ = dynlibFilename_;
2850-
dynlibFilename_ = "sourceCpp_" + createRandomizer() + dynlibExt_;
2850+
dynlibFilename_ = "sourceCpp_" + uniqueToken() + dynlibExt_;
28512851

28522852
// copy the source file to the build dir
28532853
Rcpp::Function filecopy = Rcpp::Environment::base_env()["file.copy"];
@@ -2877,15 +2877,17 @@ namespace {
28772877
throw Rcpp::file_io_error(generatedRSourcePath());
28782878

28792879
// DLLInfo - hide using . and ensure uniqueness using contextId
2880-
std::string dllInfoName = "." + contextId_ + "_DLLInfo";
2881-
std::string dllInfo = "`" + dllInfoName + "`";
2882-
rOfs << "if (!exists('" << dllInfoName << "', inherits = FALSE))" << std::endl;
2883-
rOfs << " " << dllInfo << " <- dyn.load('" << dynlibPath() << "')"
2880+
std::string dllInfo = "`." + contextId_ + "_DLLInfo`";
2881+
rOfs << dllInfo << " <- dyn.load('" << dynlibPath() << "')"
28842882
<< std::endl << std::endl;
28852883

28862884
// Generate R functions
28872885
generateR(rOfs, sourceAttributes, dllInfo);
28882886

2887+
// remove the DLLInfo
2888+
rOfs << std::endl << "rm(" << dllInfo << ")"
2889+
<< std::endl;
2890+
28892891
rOfs.close();
28902892

28912893
// discover exported functions and dependencies
@@ -3035,10 +3037,9 @@ namespace {
30353037

30363038
}
30373039

3038-
std::string createRandomizer() {
3039-
Rcpp::Function sample = Rcpp::Environment::base_env()["sample"];
3040+
std::string uniqueToken() {
30403041
std::ostringstream ostr;
3041-
ostr << Rcpp::as<int>(sample(100000, 1));
3042+
ostr << s_nextUniqueToken++;
30423043
return ostr.str();
30433044
}
30443045

@@ -3058,8 +3059,12 @@ namespace {
30583059
std::vector<std::string> plugins_;
30593060
std::vector<std::string> embeddedR_;
30603061
std::vector<FileInfo> sourceDependencies_;
3062+
static int s_nextUniqueToken;
30613063
};
30623064

3065+
// initialize next unique token
3066+
int SourceCppDynlib::s_nextUniqueToken = 0;
3067+
30633068
// Dynlib cache that allows lookup by either file path or code contents
30643069
class SourceCppDynlibCache {
30653070

0 commit comments

Comments
 (0)