自作ISSの様々な部分をスマートポインタに書き換えた結果、プログラムの最後にエラーが出てくるようになった。
./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で確保していて解放に失敗しているのを取り除けば、とりあえずは綺麗になる気がする。