Я пишу небольшую библиотеку и до сих пор добавлял исходный файл библиотеки напрямую с модульным тестом в команду add_executable
, аналогично приведенному ниже:
CMakeLists.txt (Результирующий исполняемый файл ОК)
cmake_minimum_required(VERSION 3.0)
set(CMAKE_CXX_STANDARD 17)
find_package(Eigen3 REQUIRED)
find_package(GTSAM 4.0.2 REQUIRED)
add_executable(my_test test/unit_test.cpp src/my_lib.cpp)
target_include_directories(my_test PUBLIC include ${EIGEN3_INCLUDE_DIR} ${GTSAM_INCLUDE_DIR})
target_link_libraries(my_test PUBLIC gtsam)
Все работало нормально, пока я не создал настоящую библиотеку и не связал модульный тест, как показано ниже:
CMakeLists.txt (результирующий исполняемый файл не в порядке)
cmake_minimum_required(VERSION 3.0)
set(CMAKE_CXX_STANDARD 17)
find_package(Eigen3 REQUIRED)
add_library(my_lib STATIC src/my_lib.cpp)
target_include_directories(my_lib PRIVATE include ${EIGEN3_INCLUDE_DIR})
find_package(GTSAM 4.0.2 REQUIRED)
add_executable(my_test test/unit_test.cpp)
target_include_directories(my_test PUBLIC include ${EIGEN3_INCLUDE_DIR} ${GTSAM_INCLUDE_DIR})
target_link_libraries(my_test PUBLIC gtsam my_lib)
Теперь, однако, тестовые ошибки сегмента. valgrind
сообщает следующее:
==18501== Memcheck, a memory error detector
==18501== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==18501== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==18501== Command: ./my_test
==18501==
==18501== Invalid read of size 8
==18501== at 0x509CFBB: gtsam::noiseModel::Diagonal::Sigmas(Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, bool) (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x4F3C713: _GLOBAL__sub_I_lago.cpp (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x4010732: call_init (dl-init.c:72)
==18501== by 0x4010732: _dl_init (dl-init.c:119)
==18501== by 0x40010C9: ??? (in /lib/x86_64-linux-gnu/ld-2.27.so)
==18501== Address 0x7241df8 is 8 bytes before a block of size 8 alloc'd
==18501== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18501== by 0x4ED9FD: Eigen::internal::aligned_malloc(unsigned long) (Memory.h:159)
==18501== by 0x507875B: Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >::resize(long, long) [clone .constprop.1340] (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x5085698: Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >::PlainObjectBase<Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> > >(Eigen::DenseBase<Eigen::CwiseNullaryOp<Eigen::internal::scalar_constant_op<double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> > > const&) (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x509CFA2: gtsam::noiseModel::Diagonal::Sigmas(Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, bool) (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x4F3C713: _GLOBAL__sub_I_lago.cpp (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x4010732: call_init (dl-init.c:72)
==18501== by 0x4010732: _dl_init (dl-init.c:119)
==18501== by 0x40010C9: ??? (in /lib/x86_64-linux-gnu/ld-2.27.so)
==18501==
==18501== Invalid read of size 8
==18501== at 0x4F3C71D: _GLOBAL__sub_I_lago.cpp (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x4010732: call_init (dl-init.c:72)
==18501== by 0x4010732: _dl_init (dl-init.c:119)
==18501== by 0x40010C9: ??? (in /lib/x86_64-linux-gnu/ld-2.27.so)
==18501== Address 0x7241da8 is 8 bytes before a block of size 8 alloc'd
==18501== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18501== by 0x4ED9FD: Eigen::internal::aligned_malloc(unsigned long) (Memory.h:159)
==18501== by 0x51492E1: Eigen::Matrix<double, -1, 1, 0, -1, 1>::Matrix<int>(int const&) [clone .constprop.1305] (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x4F3C6F4: _GLOBAL__sub_I_lago.cpp (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x4010732: call_init (dl-init.c:72)
==18501== by 0x4010732: _dl_init (dl-init.c:119)
==18501== by 0x40010C9: ??? (in /lib/x86_64-linux-gnu/ld-2.27.so)
==18501==
==18501== Invalid read of size 8
==18501== at 0x509CDD1: gtsam::noiseModel::Diagonal::Variances(Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, bool) (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x4F3C77A: _GLOBAL__sub_I_lago.cpp (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x4010732: call_init (dl-init.c:72)
==18501== by 0x4010732: _dl_init (dl-init.c:119)
==18501== by 0x40010C9: ??? (in /lib/x86_64-linux-gnu/ld-2.27.so)
==18501== Address 0x72420f8 is 8 bytes before a block of size 24 alloc'd
==18501== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18501== by 0x4ED9FD: Eigen::internal::aligned_malloc(unsigned long) (Memory.h:159)
==18501== by 0x509A53B: Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >::resize(long, long) [clone .constprop.1216] (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x50A4A0A: Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >::PlainObjectBase<Eigen::CwiseUnaryOp<Eigen::internal::scalar_sqrt_op<double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const> >(Eigen::DenseBase<Eigen::CwiseUnaryOp<Eigen::internal::scalar_sqrt_op<double>, Eigen::Matrix<double, -1, 1, 0, -1, 1> const> > const&) (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x509CD63: gtsam::noiseModel::Diagonal::Variances(Eigen::Matrix<double, -1, 1, 0, -1, 1> const&, bool) (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x4F3C77A: _GLOBAL__sub_I_lago.cpp (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x4010732: call_init (dl-init.c:72)
==18501== by 0x4010732: _dl_init (dl-init.c:119)
==18501== by 0x40010C9: ??? (in /lib/x86_64-linux-gnu/ld-2.27.so)
==18501== Invalid read of size 8
==18501== at 0x4F3C784: _GLOBAL__sub_I_lago.cpp (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x4010732: call_init (dl-init.c:72)
==18501== by 0x4010732: _dl_init (dl-init.c:119)
==18501== by 0x40010C9: ??? (in /lib/x86_64-linux-gnu/ld-2.27.so)
==18501== Address 0x7242098 is 8 bytes before a block of size 24 alloc'd
==18501== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18501== by 0x4ED9FD: Eigen::internal::aligned_malloc(unsigned long) (Memory.h:159)
==18501== by 0x513A304: Eigen::PlainObjectBase<Eigen::Matrix<double, -1, 1, 0, -1, 1> >::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::DenseBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&) (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x4F3C766: _GLOBAL__sub_I_lago.cpp (in /usr/local/lib/libgtsam.so.4.0.2)
==18501== by 0x4010732: call_init (dl-init.c:72)
==18501== by 0x4010732: _dl_init (dl-init.c:119)
==18501== by 0x40010C9: ??? (in /lib/x86_64-linux-gnu/ld-2.27.so)
==18501==
test_orient: /usr/local/include/eigen3/Eigen/src/Core/DenseStorage.h:128: Eigen::internal::plain_array<T, Size, MatrixOrArrayOptions, 32>::plain_array() [with T = double; int Size = 4; int MatrixOrArrayOptions = 0]: Assertion `(internal::UIntPtr(eigen_unaligned_array_assert_workaround_gcc47(array)) & (31)) == 0 && "this assertion is explained here: " "http://eigen.tuxfamily.org/dox-devel/group__TopicUnalignedArrayAssert.html" " **** READ THIS WEB PAGE !!! ****"' failed.
==18501==
==18501== Process terminating with default action of signal 6 (SIGABRT)
==18501== at 0x5F95E97: raise (raise.c:51)
==18501== by 0x5F97800: abort (abort.c:79)
==18501== by 0x5F87399: __assert_fail_base (assert.c:92)
==18501== by 0x5F87411: __assert_fail (assert.c:101)
==18501== by 0x4D98AE: Eigen::internal::plain_array<double, 4, 0, 32>::plain_array() (DenseStorage.h:128)
==18501== by 0x4D78AD: Eigen::DenseStorage<double, 4, 4, 1, 0>::DenseStorage() (DenseStorage.h:187)
==18501== by 0x4D61C7: Eigen::PlainObjectBase<Eigen::Matrix<double, 4, 1, 0, 4, 1> >::PlainObjectBase() (PlainObjectBase.h:484)
==18501== by 0x4D4DBB: Eigen::Matrix<double, 4, 1, 0, 4, 1>::Matrix() (Matrix.h:259)
==18501== by 0x4ECF6A: orient::quaternionFromAngleAxis(Eigen::Matrix<double, 3, 1, 0, 3, 1> const&) (from_angle_axis.cpp:56)
==18501== by 0x4D21C4: ____C_A_T_C_H____T_E_S_T____10() (from_angle_axis_test.cpp:95)
==18501== by 0x3F5A43: Catch::TestInvokerAsFunction::invoke() const (catch2.hpp:14054)
==18501== by 0x3F50A2: Catch::TestCase::invoke() const (catch2.hpp:13947)
==18501==
==18501== HEAP SUMMARY:
==18501== in use at exit: 42,110 bytes in 347 blocks
==18501== total heap usage: 4,871 allocs, 4,524 frees, 507,954 bytes allocated
==18501==
==18501== LEAK SUMMARY:
==18501== definitely lost: 64 bytes in 4 blocks
==18501== indirectly lost: 0 bytes in 0 blocks
==18501== possibly lost: 0 bytes in 0 blocks
==18501== still reachable: 42,046 bytes in 343 blocks
==18501== suppressed: 0 bytes in 0 blocks
==18501== Rerun with --leak-check=full to see details of leaked memory
==18501==
==18501== For counts of detected and suppressed errors, rerun with: -v
==18501== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
Ссылка в утверждении Eigen, к сожалению, не делает меня мудрее.
Мой вопрос: является ли ошибка сегмента результатом неправильной связи с моей собственной библиотекой или GTSAM? Если так, как я могу это исправить? Если нет, то должен ли я считать, что в моей библиотеке есть ошибка, которая проявляется только во втором случае?
РЕДАКТИРОВАТЬ:
Минимальный рабочий пример для воспроизведения:
include /my_lib.hpp
#pragma once
void f();
src / my_lib. cpp
#include <my_lib.hpp>
#include <unsupported/Eigen/KroneckerProduct>
void f()
{
Eigen::Matrix3d A = Eigen::Matrix3d::Random();
Eigen::Matrix<double, 9, 3> B = Eigen::Matrix<double, 9, 3>::Random();
Eigen::Matrix3d I = Eigen::Matrix3d::Identity();
Eigen::Matrix<double, 9, 3> tmp = Eigen::kroneckerProduct(I, A) * B;
}
test / unit_test. cpp
#include <my_lib.hpp>
#include <gtsam/base/numericalDerivative.h>
int main()
{
f();
return 0;
}