Eigen SIGSEGV 同时做 make_pair

Eigen SIGSEGV while doing make_pair

我正在更新约 3 年的旧代码,但在尝试将 Vector2d 和 Matrix2d 配对时崩溃了。大致来说,代码是

vector<pair<Vector2d, Matrix2d>> list;
list.resize(points.size());
Vector2d md;
Matrix2d Sd;
for(int i=0; i<n; i++) {
    // do stuff to assign elements of md and Sd
    // ...
    list[i] = make_pair(md, Sd); // SIGSEGV on this line
}

我发现了一个旧的 bug,它在堆栈的最后两层看起来很相似,但该错误被标记为已修复,并且我确认该补丁中的修复仍然存在。我尝试制作一个简单的测试用例,但它运行没有问题。有人知道问题出在哪里吗?

杂项信息:

这是回溯:

Thread 7 "flightControlle" received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fffd7152700 (LWP 12024)]
0x00000000005e846b in _mm_load_pd (__P=0x0) at /usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/include/emmintrin.h:119
119       return *(__m128d *)__P;
(gdb) bt
#0  0x00000000005e846b in _mm_load_pd (__P=0x0) at /usr/lib/gcc/x86_64-pc-linux-gnu/6.1.1/include/emmintrin.h:119
#1  Eigen::internal::pload<double __vector(2)>(Eigen::internal::unpacket_traits<double __vector(2)>::type const*) (from=0x0) at /usr/include/eigen3/Eigen/src/Core/arch/SSE/PacketMath.h:220
#2  0x000000000060310b in Eigen::internal::ploadt<double __vector(2), 1>(Eigen::internal::unpacket_traits<double __vector(2)>::type const*) (from=0x0) at /usr/include/eigen3/Eigen/src/Core/GenericPacketMath.h:290
#3  0x0000000000659523 in Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> >::packet<1> (this=0x0, rowId=0, colId=0) at /usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:184
#4  0x00000000006a40fe in Eigen::SwapWrapper<Eigen::Matrix<double, 2, 1, 0, 2, 1> >::copyPacket<Eigen::Matrix<double, 2, 1, 0, 2, 1>, 1, 1> (this=0x7fffd7150a30, rowId=0, colId=0, other=...)
    at /usr/include/eigen3/Eigen/src/Core/Swap.h:100
#5  0x00000000006a1da3 in Eigen::DenseCoeffsBase<Eigen::SwapWrapper<Eigen::Matrix<double, 2, 1, 0, 2, 1> >, 1>::copyPacketByOuterInner<Eigen::Matrix<double, 2, 1, 0, 2, 1>, 1, 1> (this=0x7fffd7150a30, outer=0, 
    inner=0, other=...) at /usr/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:548
#6  0x000000000069fa0e in Eigen::internal::assign_innervec_CompleteUnrolling<Eigen::SwapWrapper<Eigen::Matrix<double, 2, 1, 0, 2, 1> >, Eigen::Matrix<double, 2, 1, 0, 2, 1>, 0, 2>::run (dst=..., src=...)
    at /usr/include/eigen3/Eigen/src/Core/Assign.h:206
#7  0x000000000069d1f7 in Eigen::internal::assign_impl<Eigen::SwapWrapper<Eigen::Matrix<double, 2, 1, 0, 2, 1> >, Eigen::Matrix<double, 2, 1, 0, 2, 1>, 2, 2, 0>::run (dst=..., src=...)
    at /usr/include/eigen3/Eigen/src/Core/Assign.h:342
#8  0x000000000069af38 in Eigen::DenseBase<Eigen::SwapWrapper<Eigen::Matrix<double, 2, 1, 0, 2, 1> > >::lazyAssign<Eigen::Matrix<double, 2, 1, 0, 2, 1> > (this=0x7fffd7150a30, other=...)
    at /usr/include/eigen3/Eigen/src/Core/Assign.h:506
#9  0x000000000069856f in Eigen::DenseBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> >::swap<Eigen::Matrix<double, 2, 1, 0, 2, 1> > (this=0x7fffd7150c90, other=...)
    at /usr/include/eigen3/Eigen/src/Core/DenseBase.h:384
#10 0x000000000069591a in Eigen::internal::matrix_swap_impl<Eigen::Matrix<double, 2, 1, 0, 2, 1>, Eigen::Matrix<double, 2, 1, 0, 2, 1>, false>::run (a=..., b=...)
    at /usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:805
#11 0x0000000000693785 in Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> >::_swap<Eigen::Matrix<double, 2, 1, 0, 2, 1> > (this=0x7fffd7150c90, other=...)
    at /usr/include/eigen3/Eigen/src/Core/PlainObjectBase.h:682
#12 0x00000000006923c6 in Eigen::Matrix<double, 2, 1, 0, 2, 1>::swap<Eigen::Matrix<double, 2, 1, 0, 2, 1> > (this=0x7fffd7150c90, other=...) at /usr/include/eigen3/Eigen/src/Core/Matrix.h:334
#13 0x00000000006909f9 in Eigen::Matrix<double, 2, 1, 0, 2, 1>::operator=(Eigen::Matrix<double, 2, 1, 0, 2, 1>&&) (this=0x0, 
    other=<unknown type in /home/ryantr/Software/FlightControl/Rover/build/flightController, CU 0x5b3bd1, DIE 0x73ce2f>) at /usr/include/eigen3/Eigen/src/Core/Matrix.h:224
#14 0x000000000068f440 in std::pair<Eigen::Matrix<double, 2, 1, 0, 2, 1>, Eigen::Matrix<double, 2, 2, 0, 2, 2> >::operator=(std::pair<Eigen::Matrix<double, 2, 1, 0, 2, 1>, Eigen::Matrix<double, 2, 2, 0, 2, 2> >&&) (this=0x0, __p=<unknown type in /home/ryantr/Software/FlightControl/Rover/build/flightController, CU 0x5b3bd1, DIE 0x73e9e5>) at /usr/include/c++/6.1.1/bits/stl_pair.h:319
#15 0x000000000068a452 in ICSL::Quadrotor::VelocityEstimator::calcPriorDistributions (mDeltaList=std::vector of length 1, capacity 1 = {...}, SDeltaList=std::vector of length 1, capacity 1 = {...}, 
    priorDistList=std::vector of length 0, capacity 0, points=std::vector of length 1, capacity 1 = {...}, mv=..., Sv=..., mz=0.050000000000000003, varz=1, focalLength=262.0029296875, dt=0.033000000000000002, 
    omega=...) at /home/ryantr/Software/FlightControl/Rover/src/VelocityEstimator.cpp:566

这里是关于 md 和 Sd 的状态的信息,如果有区别的话:

 = {<Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> >> = {<Eigen::MatrixBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> >> = {<Eigen::DenseBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> >> = {<Eigen::internal::special_scalar_op_base<Eigen::Matrix<double, 2, 1, 0, 2, 1>, double, double, Eigen::DenseCoeffsBase<Eigen::Matrix<double, 2, 1, 0, 2, 1>, 3>, false>> = {<Eigen::DenseCoeffsBase<Eigen::Matrix<double, 2, 1, 0, 2, 1>, 3>> = {<Eigen::DenseCoeffsBase<Eigen::Matrix<double, 2, 1, 0, 2, 1>, 1>> = {<Eigen::DenseCoeffsBase<Eigen::Matrix<double, 2, 1, 0, 2, 1>, 0>> = {<Eigen::EigenBase<Eigen::Matrix<double, 2, 1, 0, 2, 1> >> = {<No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, m_storage = {m_data = {array = {-6.5748748779296875, 
          -96.418296813964844}}}}, <No data fields>}
(gdb) p Sd
 = {<Eigen::PlainObjectBase<Eigen::Matrix<double, 2, 2, 0, 2, 2> >> = {<Eigen::MatrixBase<Eigen::Matrix<double, 2, 2, 0, 2, 2> >> = {<Eigen::DenseBase<Eigen::Matrix<double, 2, 2, 0, 2, 2> >> = {<Eigen::internal::special_scalar_op_base<Eigen::Matrix<double, 2, 2, 0, 2, 2>, double, double, Eigen::DenseCoeffsBase<Eigen::Matrix<double, 2, 2, 0, 2, 2>, 3>, false>> = {<Eigen::DenseCoeffsBase<Eigen::Matrix<double, 2, 2, 0, 2, 2>, 3>> = {<Eigen::DenseCoeffsBase<Eigen::Matrix<double, 2, 2, 0, 2, 2>, 1>> = {<Eigen::DenseCoeffsBase<Eigen::Matrix<double, 2, 2, 0, 2, 2>, 0>> = {<Eigen::EigenBase<Eigen::Matrix<double, 2, 2, 0, 2, 2> >> = {<No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, <No data fields>}, m_storage = {m_data = {array = {8947423.3324944824, 110733.5419973651, 
          110733.5419973651, 13614569.654632445}}}}, <No data fields>}

这是对齐问题。看到这个intro, and in your case this page会给你答案。总之,要么使用非对齐类型:

typedef Matrix<double,2,1,DontAlign> Vector2du;
typedef Matrix<double,2,2,DontAlign> Matrix2du;
vector<pair<Vector2du, Matrix2du>> list;

或将对齐的分配器传递给 std::vector:

vector<pair<Vector2du, Matrix2du>,Eigen::aligned_allocator<pair<Vector2du, Matrix2du>>> list;