0

当我运行我的测试程序时,我收到了这个错误报告:

*** glibc detected *** /home/me/work/co/myprog/build/myprog_test: free(): invalid next size (fast): 0x00000000006d7320 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x7eb96)[0x7ffff706ab96]
/home/me/work/co/myprog/build/myprog_test(_ZN9__gnu_cxx13new_allocatorIdE10deallocateEPdm+0x20)[0x47715e]
/home/me/work/co/myprog/build/myprog_test(_ZN5boost7numeric5ublas15unbounded_arrayIdSaIdEED2Ev+0x38)[0x474aea]
/home/me/work/co/myprog/build/myprog_test(_ZN5boost7numeric5ublas6vectorIdNS1_15unbounded_arrayIdSaIdEEEED2Ev+0x19)[0x473177]
/home/me/work/co/myprog/build/myprog_test(_ZN5boost7numeric5ublas13vector_assignINS1_13scalar_assignENS1_6vectorIdNS1_15unbounded_arrayIdSaIdEEEEENS1_11zero_vectorIdS6_EEEEvRT0_RKNS1_17vector_expressionIT1_EENS1_10sparse_tagE+0x2bf)[0x47b2d9]
/home/me/work/co/myprog/build/myprog_test(_ZN5boost7numeric5ublas13vector_assignINS1_13scalar_assignENS1_6vectorIdNS1_15unbounded_arrayIdSaIdEEEEENS1_11zero_vectorIdS6_EEEEvRT0_RKNS1_17vector_expressionIT1_EE+0x26)[0x4782f4]
/home/me/work/co/myprog/build/myprog_test(_ZN5boost7numeric5ublas6vectorIdNS1_15unbounded_arrayIdSaIdEEEE6assignINS1_11zero_vectorIdS4_EEEERS6_RKNS1_17vector_expressionIT_EE+0x23)[0x4771fd]
/home/me/work/co/myprog/build/myprog_test(_ZN5boost7numeric5ublas6vectorIdNS1_15unbounded_arrayIdSaIdEEEEaSINS1_11zero_vectorIdS4_EEEERS6_RKNS1_16vector_containerIT_EE+0x4e)[0x474b52]
/home/me/work/co/myprog/build/myprog_test(_ZN9DataPointC1Ev+0x101)[0x4682d7]
/home/me/work/co/myprog/build/myprog_test(_ZN16Manager13processSampleEP6Sample+0x40)[0x46a49e]
/home/me/work/co/myprog/build/myprog_test(_ZN16Manager7addDataEP6Samplei+0x108)[0x46a8b6]
/home/me/work/co/myprog/build/myprog_test(_ZN16Manager14SetLogFileDataEP6Samplei+0x90)[0x46904a]
/home/me/work/co/myprog/build/myprog_test(_ZN36MyprogTest_testGetValuesToFilter_Test8TestBodyEv+0x6b)[0x4706a5]
/home/me/work/co/myprog/build/myprog_test(_ZN7testing8internal38HandleSehExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc+0x52)[0x49eb29]
/home/me/work/co/myprog/build/myprog_test(_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS_4TestEvEET0_PT_MS4_FS3_vEPKc+0x45)[0x499b76]
/home/me/work/co/myprog/build/myprog_test(_ZN7testing4Test3RunEv+0xb9)[0x487461]
/home/me/work/co/myprog/build/myprog_test(_ZN7testing8TestInfo3RunEv+0xf6)[0x487bb8]
/home/me/work/co/myprog/build/myprog_test(_ZN7testing8TestCase3RunEv+0xe1)[0x48815f]
/home/me/work/co/myprog/build/myprog_test(_ZN7testing8internal12UnitTestImpl11RunAllTestsEv+0x272)[0x48ce3e]
/home/me/work/co/myprog/build/myprog_test(_ZN7testing8internal38HandleSehExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKc+0x52)[0x49ffcb]
/home/me/work/co/myprog/build/myprog_test(_ZN7testing8internal35HandleExceptionsInMethodIfSupportedINS0_12UnitTestImplEbEET0_PT_MS4_FS3_vEPKc+0x45)[0x49aa62]
/home/me/work/co/myprog/build/myprog_test(_ZN7testing8UnitTest3RunEv+0x5e)[0x48bbee]
/home/me/work/co/myprog/build/myprog_test(main+0x3e)[0x4a8b76]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7ffff700d76d]
/home/me/work/co/myprog/build/myprog_test[0x466399]
======= Memory map: ========
00400000-004d2000 r-xp 00000000 08:01 11152935                           /home/me/work/co/myprog/build/myprog_test
006d1000-006d2000 r--p 000d1000 08:01 11152935                           /home/me/work/co/myprog/build/myprog_test
006d2000-006d3000 rw-p 000d2000 08:01 11152935                           /home/me/work/co/myprog/build/myprog_test
006d3000-006f4000 rw-p 00000000 00:00 0                                  [heap]
7ffff6fec000-7ffff71a1000 r-xp 00000000 08:01 12452670                   /lib/x86_64-linux-gnu/libc-2.15.so
7ffff71a1000-7ffff73a0000 ---p 001b5000 08:01 12452670                   /lib/x86_64-linux-gnu/libc-2.15.so
7ffff73a0000-7ffff73a4000 r--p 001b4000 08:01 12452670                   /lib/x86_64-linux-gnu/libc-2.15.so
7ffff73a4000-7ffff73a6000 rw-p 001b8000 08:01 12452670                   /lib/x86_64-linux-gnu/libc-2.15.so
7ffff73a6000-7ffff73ab000 rw-p 00000000 00:00 0
7ffff73ab000-7ffff73c0000 r-xp 00000000 08:01 12455438                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff73c0000-7ffff75bf000 ---p 00015000 08:01 12455438                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff75bf000-7ffff75c0000 r--p 00014000 08:01 12455438                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff75c0000-7ffff75c1000 rw-p 00015000 08:01 12455438                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7ffff75c1000-7ffff76bc000 r-xp 00000000 08:01 12452678                   /lib/x86_64-linux-gnu/libm-2.15.so
7ffff76bc000-7ffff78bb000 ---p 000fb000 08:01 12452678                   /lib/x86_64-linux-gnu/libm-2.15.so
7ffff78bb000-7ffff78bc000 r--p 000fa000 08:01 12452678                   /lib/x86_64-linux-gnu/libm-2.15.so
7ffff78bc000-7ffff78bd000 rw-p 000fb000 08:01 12452678                   /lib/x86_64-linux-gnu/libm-2.15.so
7ffff78bd000-7ffff799f000 r-xp 00000000 08:01 794196                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7ffff799f000-7ffff7b9e000 ---p 000e2000 08:01 794196                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7ffff7b9e000-7ffff7ba6000 r--p 000e1000 08:01 794196                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7ffff7ba6000-7ffff7ba8000 rw-p 000e9000 08:01 794196                     /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.16
7ffff7ba8000-7ffff7bbd000 rw-p 00000000 00:00 0
7ffff7bbd000-7ffff7bd5000 r-xp 00000000 08:01 12452672                   /lib/x86_64-linux-gnu/libpthread-2.15.so
7ffff7bd5000-7ffff7dd4000 ---p 00018000 08:01 12452672                   /lib/x86_64-linux-gnu/libpthread-2.15.so
7ffff7dd4000-7ffff7dd5000 r--p 00017000 08:01 12452672                   /lib/x86_64-linux-gnu/libpthread-2.15.so
7ffff7dd5000-7ffff7dd6000 rw-p 00018000 08:01 12452672                   /lib/x86_64-linux-gnu/libpthread-2.15.so
7ffff7dd6000-7ffff7dda000 rw-p 00000000 00:00 0
7ffff7dda000-7ffff7dfc000 r-xp 00000000 08:01 12452684                   /lib/x86_64-linux-gnu/ld-2.15.so
7ffff7fd6000-7ffff7fdb000 rw-p 00000000 00:00 0
7ffff7ff7000-7ffff7ffb000 rw-p 00000000 00:00 0
7ffff7ffb000-7ffff7ffc000 r-xp 00000000 00:00 0                          [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00022000 08:01 12452684                   /lib/x86_64-linux-gnu/ld-2.15.so
7ffff7ffd000-7ffff7fff000 rw-p 00023000 08:01 12452684                   /lib/x86_64-linux-gnu/ld-2.15.so
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0                          [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

我已经通过 gdb 运行它,导致它的行间接地是这个构造函数调用,当它到达构造函数中的行时

DataPointPtr data(new DataPoint());
=>
gyro_stdev = zero_vector;

使用 DataPoint 和 Ptr 的这些定义:

typedef boost::numeric::ublas::vector<double> vector;

struct DataPoint {
  DataPoint(void);
  long timestamp;
  bool derived;

  vector accel;
  vector accel_filtered;

  vector gyro_filtered;
  vector gyro_stdev;

  vector gyro;

  vector velocity;
  vector position;
  vector orientation;

  vector gravity;
};

typedef boost::shared_ptr<DataPoint> DataPointPtr;

boost::numeric::ublas::zero_vector<double> zero_vector(3);

DataPoint::DataPoint(void) {
  derived = false;

  accel = zero_vector;
  accel_filtered = zero_vector;

  gyro_filtered = zero_vector;
  gyro_stdev = zero_vector;

  gyro = zero_vector;

  position = zero_vector;
  velocity = zero_vector;
  orientation = zero_vector;
  gravity = zero_vector;

}

我也通过 valgrind 运行了相同的程序,我得到了难以置信的输出量,其中大部分看起来像这样,仅取决于我使用的三角函数(sin、tan、atan2 等)

==4161== Conditional jump or move depends on uninitialised value(s)
==4161==    at 0x536CC9D: __sin_sse2 (s_sin.c:115)
==4161==    by 0x46B23C: AccelGyroManager::getGyroEstimate(long, boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double, std::allocator<double> > >, boost::numeric::ublas::vector<double, boost::numeric::ublas::unbounded_array<double, std::allocator<double> > >) (AccelGyroManager.cxx:659)
==4161==    by 0x46BD53: AccelGyroManager::deriveData(int) (AccelGyroManager.cxx:753)
==4161==    by 0x46957A: AccelGyroManager::GetEstimate(long, float*, float*, float*, float*, float*, float*) (AccelGyroManager.cxx:294)
==4161==    by 0x467150: AgmanDllTest_testDeriveInterpolatedData_Test::TestBody() (agman_test.cxx:144)
==4161==    by 0x49EB28: void testing::internal::HandleSehExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2090)
==4161==    by 0x499B75: void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(), char const*) (gtest.cc:2126)
==4161==    by 0x487460: testing::Test::Run() (gtest.cc:2162)
==4161==    by 0x487BB7: testing::TestInfo::Run() (gtest.cc:2338)
==4161==    by 0x48815E: testing::TestCase::Run() (gtest.cc:2445)
==4161==    by 0x48CE3D: testing::internal::UnitTestImpl::RunAllTests() (gtest.cc:4237)
==4161==    by 0x49FFCA: bool testing::internal::HandleSehExceptionsInMethodIfSupported<testing::internal::UnitTestImpl, bool>(testing::internal::UnitTestImpl*, bool (testing::internal::UnitTestImpl::*)(), char const*) (gtest.cc:2090)
==4161==

这个问题让我有点困惑。有没有可能我的内存不足?在程序的这一点之前,这个完全相同的构造函数调用成功了大约 400 次。

而且 valgrind 对 s_sin.c 的引用也令人困惑,我在任何地方都找不到这个文件..

非常感谢任何有关查看或浏览内容的建议或建议。

4

2 回答 2

3

所以我发现了我的问题。正如 Mats Petersson 建议的那样,我的问题实际上是数组溢出。事实证明,我在我的实用程序中为我的单元测试埋下了这个小宝石:

SampleArray createPredictableSamples(int count) {
  SampleArray samples(new Sample[100]);
  for (int i = 0; i < count; ++i) {
  ... do stuff
  }
  return samples;
}

(注意在方法参数化时创建大小为 100 的静态数组...)

所以请记住,测试代码也有错误!

这是我用来发现这一点的方法。

当我发布我的问题时,自上次运行测试以来,我已经做了很多更改。运行的输出

valgrind --tool=memcheck --leak-check=yes ./test

正因为如此,所以有点不知所措。所以我退出了大部分更改(使用我的版本控制来保持它们可用),然后将它们作为功能集一一重新应用。

每次我引入一个变更集时,我都会重新运行测试,并使用 valgrind 检查内存错误。最后,我做了一个改变(改变我的测试数组大小),产生了大量的输出。我搜索了(正如 valgrind 建议的那样)“写入”到未初始化的内存(即缓冲区溢出)。你瞧,它把我引向了问题所在,行号等等。

在此过程中,我还在测试代码中发现了其他几个内存泄漏。现在,我还有更多的工作要做清理内存泄漏的测试代码,但我至少已经摆脱了缓冲区溢出。

感谢 Mats、David 和 vonbrand 为我指明了正确的方向!

于 2013-02-10T01:29:22.867 回答
2

很高兴你已经运行了 valgrind!现在我认为我们应该解决它的担忧。

如果getGyroEstimate()正在读取硬件设备,即使事情正确完成,valgrind 也可能将该值视为未初始化。--gen-suppressions如果您认为是这种情况(如果不是,甚至可能是暂时的),您可以将其添加到 valgrind“抑制”文件中(如果您使用该选项,valgrind 可以帮助您半自动地执行此操作)。然后你就不会被这个可能无害的警告分心,并且可以继续修复它可能会抱怨的其他事情(其中一些可能是你崩溃的根本原因)。

于 2013-02-10T01:17:24.520 回答