FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

スマートポインタを導入することでメモリリークが検出されるようになったのでValgrindで解析

自作ISSの様々な部分をスマートポインタに書き換えた結果、プログラムの最後にエラーが出てくるようになった。

github.com

./swimmer_mips --binfile=../benchmarks/releases/coremark_v1.0_mips4_gcc49_O2/coremark.bin --debug --out coremark.log --max 10000000 --debug_func --debug_gvar
*** Error in `./swimmer_mips': munmap_chunk(): invalid pointer: 0x00000000020f80a0 ***
Aborted (core dumped)

最初は何だか分からなかったのだが、念のためvalgrindをかけて、解析してみることにした。

valgrind --log-file="output.log" --leak-check=full swimmer_mips --binfile=../benchmarks/releases/coremark_v1.0_mips4_gcc49_O2/coremark.bin --debug --out coremark.log --max 10000000 --debug_func --debug_gvar

output.logにvalgrindのログが出力されている。

==8720== Invalid write of size 8
==8720==    at 0x42F1A5: std::unique_ptr<ModuleIde, std::default_delete<ModuleIde> >::~unique_ptr() (unique_ptr.h:237)
==8720==    by 0x42EB5A: MipsEnv::~MipsEnv() (in /home/vagrant/swimmer_mips/build_mips/swimmer_mips)
==8720==    by 0x42EBB3: std::default_delete<MipsEnv>::operator()(MipsEnv*) const (unique_ptr.h:76)
==8720==    by 0x42E976: std::unique_ptr<MipsEnv, std::default_delete<MipsEnv> >::~unique_ptr() (unique_ptr.h:236)
==8720==    by 0x42DA94: main (swimmer_main.cpp:233)
==8720==  Address 0x65df430 is 208 bytes inside a block of size 480 free'd
==8720==    at 0x4C2D2E0: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8720==    by 0x44D980: ModuleIde::~ModuleIde() (module_ide.cpp:173)
==8720==    by 0x42F777: std::default_delete<ModuleIde>::operator()(ModuleIde*) const (unique_ptr.h:76)
==8720==    by 0x42F1A0: std::unique_ptr<ModuleIde, std::default_delete<ModuleIde> >::~unique_ptr() (unique_ptr.h:236)
==8720==    by 0x42EB5A: MipsEnv::~MipsEnv() (in /home/vagrant/swimmer_mips/build_mips/swimmer_mips)
==8720==    by 0x42EBB3: std::default_delete<MipsEnv>::operator()(MipsEnv*) const (unique_ptr.h:76)
==8720==    by 0x42E976: std::unique_ptr<MipsEnv, std::default_delete<MipsEnv> >::~unique_ptr() (unique_ptr.h:236)
==8720==    by 0x42DA94: main (swimmer_main.cpp:233)

あ、良くみると解放してはいけないところで解放してる!

     m_status = 0x40;  // RDY = 1
 }
-
-
-ModuleIde::~ModuleIde ()
-{
-    delete m_env;

このm_envは親である環境クラスであり、これを解放するとプログラムは動かなくなってしまう。このデストラクタは最後にしか呼ばれないため、今まで気がつかなかったのか。。。 とりあえずこれでvalgrindのエラーはかなり減った。あとは、mallocで確保していて解放に失敗しているのを取り除けば、とりあえずは綺麗になる気がする。

github.com