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

このため少し圧倒されました。そのため、これらの変更のほとんどを取り消して(バージョン管理を使用して使用可能な状態に保ちます)、機能セットとして1つずつ再適用しました。

1つの変更セットを導入するたびに、テストを再実行し、valgrindを使用してメモリエラーをチェックしました。最後に、大量の出力を生成する1つの変更(テスト配列サイズの変更)を行いました。私はそれを(valgrindが示唆するように)初期化されていないメモリへの「書き込み」(つまり、バッファオーバーラン)を検索しました。そして、見よ、それは私を問題、行番号、そしてすべてに正しく導きます。

途中で、テストコードに他のいくつかのメモリリークも見つかりました。現在、メモリリークのテストコードをクリーンアップする作業はまだ残っていますが、少なくともバッファオーバーランは解消されています。

私を正しい方向に向けてくれたMats、David、vonbrandに感謝します!

于 2013-02-10T01:29:22.867 に答える
2

すでにvalgrindを実行したのは素晴らしいことです!今、私たちはその懸念に対処すべきだと思います。

がハードウェアデバイスを読み取っている場合getGyroEstimate()、処理が正しく行われている場合でも、valgrindが値を初期化されていないと見なしている可能性があります。これが当てはまると思われる場合(そしてそうでない場合でも一時的に)、valgrindの「抑制」ファイルに追加できます(--gen-suppressionsオプションを使用すると、valgrindはこれを半自動で行うのに役立ちます)。そうすれば、このおそらく無害な警告に気を取られることはなく、おそらく不平を言う他の問題の修正に進むことができます(そのうちのいくつかはおそらくクラッシュの根本的な原因です)。

于 2013-02-10T01:17:24.520 に答える