Skip to content

CVODES callbacks to C++ not passing exceptions in g++6 #348

@bob-carpenter

Description

@bob-carpenter

Summary:

With g++6, If the ODE system throws an exception, it terminates Stan rather than being caught.

Description:

C++ calls to C which invoke callbacks to C++ with exceptions provoke undefined behavior (cross-language). In g++6 this crashes Stan. With other compilers, resources may leak even if excpetions are caught.

Reproducible Steps:

Existing unit tests for integrate_ode_bdf pass in compilers other than g++6 because C++ can catch the excpetions after the call to CVODES, but they terminate the C++ process in g++6. The failing tests are in the following two files, marked with TODO(carpenter): g++ failure on the branch bugfix/0327-log-int for fixing issue #327.

  • test/unit/math/rev/mat/functor/integrate_ode_bdf_prim_test.cpp
  • test/unit/math/rev/mat/functor/integrate_ode_bdf_rev_test.cpp

Current Output:

~/cmdstan/stan/lib/stan_math(bugfix/0327-log-int)$ ./runTests.py -j4 test/unit/math/rev/mat/functor/integrate_ode_bdf_rev_test.cpp 
...
Running main() from gtest_main.cc
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from StanAgradRevOde_integrate_ode
[ RUN      ] StanAgradRevOde_integrate_ode.harmonic_oscillator_finite_diff
terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check: __n (which is 0) >= this->size() (which is 0)
test/unit/math/rev/mat/functor/integrate_ode_bdf_rev_test --gtest_output="xml:test/unit/math/rev/mat/functor/integrate_ode_bdf_rev_test.xml" failed
exit now (08/15/16 13:02:52 CEST)

Expected Output:

Passing unit tests.

Additional Information:

When I started tracking this down, I first thought it might be an issue with std::vector, but I don't think that's it. I then thought it might be an issue with how g++ allows control of visibility, because without visibility, you won't be able to catch exceptions:

But I have no idea how to fix this other than not throwing exceptions from the system ODE function. Instead, we might need to catch all exceptions, record them somewhere that we can pass back to C++, then rethrow them when we return. The problem with that is that we do want to stop the C function trying to integrate the ODE sytem.

Current Version:

v2.11.0

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions