[Rcpp-devel] Interrupts in compiled code.

Dirk Eddelbuettel edd at debian.org
Wed Dec 8 22:02:18 CET 2010


On 8 December 2010 at 13:41, Andrew Redd wrote:
| I have an MCMC chain that runs entirely in c++ with Rcpp.  It sometimes runs
| for a vary long time and I want to interrupt it.  Is there an efficient easy
| way to include catching an interupt signal and either aborting or returning
| results to that point?  This might be understood well, if so I apologize.

Great question.  

Here is a simple example that uses a standard C interrupt handler to set a
standard C++ exception to abort:

----------------------------------------------------------------

#include <csignal>
#include <Rcpp.h>

void intHandler(int dummy=0) {
  std::cerr << "In intHandler" << std::endl;
  throw std::runtime_error("Interception caught");
}

RcppExport SEXP foo(void) {

  try {

    signal(SIGINT, intHandler);
    signal(SIGKILL, intHandler);
    
    while (true) {
      sleep(1);			// not doing much
    }
    return R_NilValue;

  } catch(std::exception &ex) { 
    std::cerr << "In catch of std::exeception" << std::endl;
    // here you insert some clenup
    forward_exception_to_r(ex); 

  } catch(...) { 
    ::Rf_error("c++ exception (unknown reason)"); 
  }

  return R_NilValue;
}

----------------------------------------------------------------

which I then quickly turned into a shared object, load and ran at the
command-line [1]

edd at max:/tmp/andrew$ PKG_CPPFLAGS=`r -e'Rcpp:::CxxFlags()'` PKG_LIBS=`r -e'Rcpp:::LdFlags()'` R CMD SHLIB int2throw.cpp
ccache g++ -I/usr/share/R/include -I/usr/local/lib/R/site-library/Rcpp/include     -fpic  -g -O3 -Wall -pipe -pedantic -Wno-variadic-macros -c int2throw.cpp -o int2throw.o
g++ -shared -o int2throw.so int2throw.o -L/usr/local/lib/R/site-library/Rcpp/lib -lRcpp -Wl,-rpath,/usr/local/lib/R/site-library/Rcpp/lib -L/usr/lib64/R/lib -lR
edd at max:/tmp/andrew$ r -e'dyn.load("int2throw.so"); .Call("foo")'
^CIn intHandler
In catch of std::exeception
Error in cpp_exception(message = "Interception caught", class = "std::runtime_error") :
  Interception caught
Execution halted
edd at max:/tmp/andrew$
edd at max:/tmp/andrew$


After lauching it from the one-line littler (r) expression, I pressed Ctrl-C
which then got us into the interrupt which threw the exception which lead to
the end.

In Rscript it looks a little more orderly on the unwind:

edd at max:/tmp/andrew$ Rscript -e 'dyn.load("int2throw.so"); .Call("foo")'
  C-c C-cIn intHandler
In catch of std::exeception
Error in cpp_exception(message = "Interception caught", class = "std::runtime_error") : 
  Interception caught
Calls: .Call -> cpp_exception
Execution halted
edd at max:/tmp/andrew$ 


Hope this helps,  Dirk


[1] Not sure why I didn't use inline today...


-- 
Dirk Eddelbuettel | edd at debian.org | http://dirk.eddelbuettel.com


More information about the Rcpp-devel mailing list