It doesn’t take ode or matrix_exp to crash:
auto nonstiff(Eigen::MatrixXd A, Eigen::VectorXd y0) {
std::vector<std::vector<double>> y(1, {2, 2});
return stan::math::to_vector(y[0]) - A * y0;
}
TEST(ode, debug) {
Eigen::MatrixXd A(2,2);
A << 1, 1, 1, 1;
Eigen::VectorXd y0(2);
y0 << 1, 1;
auto xx = nonstiff(A, y0);
std::cout << xx << "\n";
}
Output:
Running main() from lib/gtest_1.8.1/src/gtest_main.cc
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from ode
[ RUN ] ode.debug
=================================================================
==39618==ERROR: AddressSanitizer: heap-use-after-free on address 0x602000000330 at pc 0x00010963d323 bp 0x7fff5669fc10 sp 0x7fff5669fc08
READ of size 16 at 0x602000000330 thread T0
#0 0x10963d322 in double vector[2] Eigen::internal::pload<double vector[2]>(Eigen::internal::unpacket_traits<double vector[2]>::type const*) PacketMath.h:307
#1 0x10963d2cc in double vector[2] Eigen::internal::evaluator<Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> > >::packet<16, double vector[2]>(long) const CoreEvaluators.h:204
#2 0x10963d146 in void Eigen::internal::generic_dense_assignment_kernel<Eigen::internal::evaluator<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, Eigen::internal::evaluator<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, Eigen::internal::assign_op<double, double>, 0>::assignPacket<16, 16, double vector[2]>(long) AssignEvaluator.h:658
#3 0x10963cd9f in Eigen::internal::dense_assignment_loop<Eigen::internal::generic_dense_assignment_kernel<Eigen::internal::evaluator<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, Eigen::internal::evaluator<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, Eigen::internal::assign_op<double, double>, 0>, 3, 0>::run(Eigen::internal::generic_dense_assignment_kernel<Eigen::internal::evaluator<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, Eigen::internal::evaluator<Eigen::Matrix<double, -1, 1, 0, -1, 1> >, Eigen::internal::assign_op<double, double>, 0>&) AssignEvaluator.h:416
#4 0x10963ca2e in void Eigen::internal::call_dense_assignment_loop<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::internal::assign_op<double, double> >(Eigen::Matrix<double, -1, 1, 0, -1, 1>&, Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, Eigen::internal::assign_op<double, double> const&) AssignEvaluator.h:741
#5 0x10963c821 in Eigen::internal::Assignment<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::internal::assign_op<double, double>, Eigen::internal::Dense2Dense, void>::run(Eigen::Matrix<double, -1, 1, 0, -1, 1>&, Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, Eigen::internal::assign_op<double, double> const&) AssignEvaluator.h:879
#6 0x10963c70c in void Eigen::internal::call_assignment_no_alias<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::internal::assign_op<double, double> >(Eigen::Matrix<double, -1, 1, 0, -1, 1>&, Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, Eigen::internal::assign_op<double, double> const&) AssignEvaluator.h:836
#7 0x10963c61a in void Eigen::internal::assignment_from_xpr_op_product<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0>, Eigen::internal::assign_op<double, double>, Eigen::internal::sub_assign_op<double, double> >::run<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<double, double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0> const>, Eigen::internal::assign_op<double, double> >(Eigen::Matrix<double, -1, 1, 0, -1, 1>&, Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<double, double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0> const> const&, Eigen::internal::assign_op<double, double> const&) ProductEvaluators.h:217
#8 0x10963c4bc in void Eigen::internal::call_assignment_no_alias<Eigen::Matrix<double, -1, 1, 0, -1, 1>, Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<double, double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0> const>, Eigen::internal::assign_op<double, double> >(Eigen::Matrix<double, -1, 1, 0, -1, 1>&, Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<double, double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0> const> const&, Eigen::internal::assign_op<double, double> const&) AssignEvaluator.h:836
#9 0x10963c3fc in Eigen::Matrix<double, -1, 1, 0, -1, 1>& Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >::_set_noalias<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<double, double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0> const> >(Eigen::DenseBase<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<double, double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0> const> > const&) PlainObjectBase.h:728
#10 0x10963c2bc in void Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >::_init1<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<double, double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0> const>, Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<double, double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0> const> >(Eigen::DenseBase<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<double, double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0> const> > const&) PlainObjectBase.h:812
#11 0x10963c276 in Eigen::Matrix<double, -1, 1, 0, -1, 1>::Matrix<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<double, double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0> const> >(Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<double, double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0> const> const&) Matrix.h:296
#12 0x10963c22c in Eigen::Matrix<double, -1, 1, 0, -1, 1>::Matrix<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<double, double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0> const> >(Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<double, double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0> const> const&) Matrix.h:294
#13 0x10963bd2e in Eigen::DenseBase<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<double, double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0> const> >::eval() const DenseBase.h:406
#14 0x109570bc1 in std::__1::basic_ostream<char, std::__1::char_traits<char> >& Eigen::operator<<<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<double, double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0> const> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, Eigen::DenseBase<Eigen::CwiseBinaryOp<Eigen::internal::scalar_difference_op<double, double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const, Eigen::Product<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>, 0> const> > const&) IO.h:220
#15 0x10956fff4 in ode_debug_Test::TestBody() debug_test.cpp:19
#16 0x10975dcde in void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) gtest.cc:2443
#17 0x1096936cb in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) gtest.cc:2479
#18 0x10969319f in testing::Test::Run() gtest.cc:2517
#19 0x10969717a in testing::TestInfo::Run() gtest.cc:2693
#20 0x10969b2a9 in testing::TestCase::Run() gtest.cc:2811
#21 0x1096d0064 in testing::internal::UnitTestImpl::RunAllTests() gtest.cc:5177
#22 0x10976d899 in bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) gtest.cc:2443
#23 0x1096cefb5 in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) gtest.cc:2479
#24 0x1096cea50 in testing::UnitTest::Run() gtest.cc:4786
#25 0x1096477b0 in RUN_ALL_TESTS() gtest.h:2341
#26 0x10964772e in main gtest_main.cc:45
#27 0x7fffccb57234 in start (libdyld.dylib:x86_64+0x5234)
0x602000000330 is located 0 bytes inside of 16-byte region [0x602000000330,0x602000000340)
freed by thread T0 here:
#0 0x1099bc066 in wrap_free (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x59066)
#1 0x1095789f4 in Eigen::internal::aligned_free(void*) Memory.h:177
#2 0x1095789d4 in void Eigen::internal::conditional_aligned_free<true>(void*) Memory.h:230
#3 0x1095789ab in void Eigen::internal::conditional_aligned_delete_auto<double, true>(double*, unsigned long) Memory.h:416
#4 0x109578fc2 in Eigen::DenseStorage<double, -1, -1, 1, 0>::~DenseStorage() DenseStorage.h:542
#5 0x109578f34 in Eigen::DenseStorage<double, -1, -1, 1, 0>::~DenseStorage() DenseStorage.h:542
#6 0x109578f14 in Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >::~PlainObjectBase() PlainObjectBase.h:98
#7 0x109578ef4 in Eigen::Matrix<double, -1, 1, 0, -1, 1>::~Matrix() Matrix.h:178
#8 0x10956f804 in Eigen::Matrix<double, -1, 1, 0, -1, 1>::~Matrix() Matrix.h:178
#9 0x10956ef9a in nonstiff(Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>) debug_test.cpp:10
#10 0x10956ffc7 in ode_debug_Test::TestBody() debug_test.cpp:18
#11 0x10975dcde in void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) gtest.cc:2443
#12 0x1096936cb in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) gtest.cc:2479
#13 0x10969319f in testing::Test::Run() gtest.cc:2517
#14 0x10969717a in testing::TestInfo::Run() gtest.cc:2693
#15 0x10969b2a9 in testing::TestCase::Run() gtest.cc:2811
#16 0x1096d0064 in testing::internal::UnitTestImpl::RunAllTests() gtest.cc:5177
#17 0x10976d899 in bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) gtest.cc:2443
#18 0x1096cefb5 in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) gtest.cc:2479
#19 0x1096cea50 in testing::UnitTest::Run() gtest.cc:4786
#20 0x1096477b0 in RUN_ALL_TESTS() gtest.h:2341
#21 0x10964772e in main gtest_main.cc:45
#22 0x7fffccb57234 in start (libdyld.dylib:x86_64+0x5234)
previously allocated by thread T0 here:
#0 0x1099bbe9c in wrap_malloc (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x58e9c)
#1 0x10958b689 in Eigen::internal::aligned_malloc(unsigned long) Memory.h:159
#2 0x10958b614 in void* Eigen::internal::conditional_aligned_malloc<true>(unsigned long) Memory.h:214
#3 0x10958b5b4 in double* Eigen::internal::conditional_aligned_new_auto<double, true>(unsigned long) Memory.h:374
#4 0x10958d1fb in Eigen::DenseStorage<double, -1, -1, 1, 0>::resize(long, long, long) DenseStorage.h:557
#5 0x1096376be in Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >::resize(long, long) PlainObjectBase.h:293
#6 0x10963737f in void Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >::resizeLike<Eigen::Map<Eigen::Matrix<double, -1, 1, 0, -1, 1> const, 0, Eigen::Stride<0, 0> > >(Eigen::EigenBase<Eigen::Map<Eigen::Matrix<double, -1, 1, 0, -1, 1> const, 0, Eigen::Stride<0, 0> > > const&) PlainObjectBase.h:375
#7 0x1096371d6 in Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >::PlainObjectBase<Eigen::Map<Eigen::Matrix<double, -1, 1, 0, -1, 1> const, 0, Eigen::Stride<0, 0> > >(Eigen::DenseBase<Eigen::Map<Eigen::Matrix<double, -1, 1, 0, -1, 1> const, 0, Eigen::Stride<0, 0> > > const&) PlainObjectBase.h:536
#8 0x10963715c in Eigen::Matrix<double, -1, 1, 0, -1, 1>::Matrix<Eigen::Map<Eigen::Matrix<double, -1, 1, 0, -1, 1> const, 0, Eigen::Stride<0, 0> > >(Eigen::EigenBase<Eigen::Map<Eigen::Matrix<double, -1, 1, 0, -1, 1> const, 0, Eigen::Stride<0, 0> > > const&) Matrix.h:379
#9 0x109636c5c in Eigen::Matrix<double, -1, 1, 0, -1, 1>::Matrix<Eigen::Map<Eigen::Matrix<double, -1, 1, 0, -1, 1> const, 0, Eigen::Stride<0, 0> > >(Eigen::EigenBase<Eigen::Map<Eigen::Matrix<double, -1, 1, 0, -1, 1> const, 0, Eigen::Stride<0, 0> > > const&) Matrix.h:380
#10 0x10956f3d9 in Eigen::Matrix<double, -1, 1, 0, -1, 1> stan::math::to_vector<double>(std::__1::vector<double, std::__1::allocator<double> > const&) to_vector.hpp:25
#11 0x10956eeb3 in nonstiff(Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, 1, 0, -1, 1>) debug_test.cpp:10
#12 0x10956ffc7 in ode_debug_Test::TestBody() debug_test.cpp:18
#13 0x10975dcde in void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) gtest.cc:2443
#14 0x1096936cb in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) gtest.cc:2479
#15 0x10969319f in testing::Test::Run() gtest.cc:2517
#16 0x10969717a in testing::TestInfo::Run() gtest.cc:2693
#17 0x10969b2a9 in testing::TestCase::Run() gtest.cc:2811
#18 0x1096d0064 in testing::internal::UnitTestImpl::RunAllTests() gtest.cc:5177
#19 0x10976d899 in bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) gtest.cc:2443
#20 0x1096cefb5 in bool testing::internal::HandleExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) gtest.cc:2479
#21 0x1096cea50 in testing::UnitTest::Run() gtest.cc:4786
#22 0x1096477b0 in RUN_ALL_TESTS() gtest.h:2341
#23 0x10964772e in main gtest_main.cc:45
#24 0x7fffccb57234 in start (libdyld.dylib:x86_64+0x5234)
SUMMARY: AddressSanitizer: heap-use-after-free PacketMath.h:307 in double vector[2] Eigen::internal::pload<double vector[2]>(Eigen::internal::unpacket_traits<double vector[2]>::type const*)
Shadow bytes around the buggy address:
0x1c0400000010: fa fa 00 04 fa fa 00 00 fa fa 00 06 fa fa 00 fa
0x1c0400000020: fa fa 00 fa fa fa 00 fa fa fa 00 00 fa fa 00 fa
0x1c0400000030: fa fa 00 fa fa fa 00 fa fa fa 00 fa fa fa 00 fa
0x1c0400000040: fa fa 04 fa fa fa 00 fa fa fa 04 fa fa fa 00 fa
0x1c0400000050: fa fa 00 00 fa fa 00 00 fa fa fd fd fa fa fd fd
=>0x1c0400000060: fa fa fd fd fa fa[fd]fd fa fa 00 00 fa fa fa fa
0x1c0400000070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c0400000080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c0400000090: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c04000000a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x1c04000000b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==39618==ABORTING
Abort trap: 6
On the other hand the run passes when the return of nonstiff
is specified as VectorXd
. So my guess is it has to do with auto
type deduction of Eigen objects.