首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单独编译库源文件时单元测试中的Seg错误

单独编译库源文件时单元测试中的Seg错误
EN

Stack Overflow用户
提问于 2020-05-03 15:31:51
回答 1查看 118关注 0票数 1

我正在编写一个小型库,到目前为止,我在add_executable命令中使用单元测试直接添加了库源文件,类似于以下所示:

CMakeLists.txt (产生的可执行文件OK)

代码语言:javascript
复制
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 (由此产生的可执行文件不确定)

代码语言:javascript
复制
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)

但是,现在测试seg错误。valgrind报告如下:

代码语言:javascript
复制
==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)

不幸的是,本征中的链接使我一点也不明智。

我的问题是: seg的错误是错误地链接到我自己的库或GTSAM的结果吗?如果是的话,我怎样才能解决它呢?如果不是,我是否应该假设我的库中有一个只在第二种情况下才能显示出来的bug?

编辑:

复制的最小工作示例:

包括/my_lib.hpp

代码语言:javascript
复制
#pragma once
void f();

src/my_lib.cpp

代码语言:javascript
复制
#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;
}

测试/单元测试.unit

代码语言:javascript
复制
#include <my_lib.hpp>
#include <gtsam/base/numericalDerivative.h>

int main()
{
  f();
  return 0;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-04 09:03:10

库使用Eigen3库,这也是测试中使用的gtsam库的一部分。您需要确保在这两种情况下都使用相同的 Eigen3库,否则可能会发生细微的bug(就像您观察到的那样)。

从技术上讲,您的库和基于gtsam的测试是单独的对象文件,因此它们是独立编译的,它们都是正确的

链接器可以执行不必要的优化,比如从这些对象文件中合并函数。例如,如果这些函数具有相同的名称。如果您找到了一种方法来禁止对链接器进行这种优化,那么即使gtsam为您的库使用了不兼容的Eigen3库,结果测试也可以正常工作。

但是,从项目稳定性的角度来看,禁用链接器优化是一种非常微妙的方法。只把这种方式作为最后的手段。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61577040

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档