valgrind
ある目的で, こんなテストプログラムを書いてみた.
#include <iostream> #include <vector> struct X { std::vector<X*> children; X () { std::cout << "+[" << this << "]\n"; } ~X () { for( size_t i = 0; i < children.size(); ++i ){ if( children[i] ){ delete children[i]; children[i] = 0; } } std::cout << "-[" << this << "]\n"; } }; int main () { X x; x.children.resize(2); x.children[0] = new X; x.children[1] = new X; x.children[0]->children.resize(2); x.children[0]->children[0] = new X; x.children[0]->children[1] = new X; return 0; }
実行結果
$ ./a.out +[0x7fff9877a320] +[0x602030] +[0x602050] +[0x602090] +[0x6020b0] -[0x602090] -[0x6020b0] -[0x602030] -[0x602050] -[0x7fff9877a320]
とりあえず問題なく動くようだが, さて, 本当に大丈夫だろうか, と思い念のため valgrind を(人生で二度目に)使ってみた.
$ valgrind ./a.out ==25938== Memcheck, a memory error detector. ==25938== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al. ==25938== Using LibVEX rev 1658, a library for dynamic binary translation. ==25938== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP. ==25938== Using valgrind-3.2.1-Debian, a dynamic binary instrumentation framewor k. ==25938== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al. ==25938== For more details, rerun with: -v ==25938== ==25938== Conditional jump or move depends on uninitialised value(s) ==25938== at 0x40151F1: (within /lib/ld-2.7.so) ==25938== by 0x4005052: (within /lib/ld-2.7.so) ==25938== by 0x4007BA8: (within /lib/ld-2.7.so) ==25938== by 0x400302E: (within /lib/ld-2.7.so) ==25938== by 0x4013C14: (within /lib/ld-2.7.so) ==25938== by 0x4001318: (within /lib/ld-2.7.so) ==25938== by 0x4000A67: (within /lib/ld-2.7.so) vex amd64->IR: unhandled instruction bytes: 0x66 0x66 0x66 0x66 ==25938== valgrind: Unrecognised instruction at address 0x4015A71. ==25938== Your program just tried to execute an instruction that Valgrind ==25938== did not recognise. There are two possible reasons for this. ==25938== 1. Your program has a bug and erroneously jumped to a non-code ==25938== location. If you are running Memcheck and you just saw a ==25938== warning about a bad jump, it's probably your program's fault. ==25938== 2. The instruction is legitimate but Valgrind doesn't handle it, ==25938== i.e. it's Valgrind's fault. If you think this is the case or ==25938== you are not sure, please let us know and we'll try to fix it. ==25938== Either way, Valgrind will now raise a SIGILL signal which will ==25938== probably kill your program. ==25938== ==25938== Process terminating with default action of signal 4 (SIGILL) ==25938== Illegal opcode at address 0x4015A71 ==25938== at 0x4015A71: (within /lib/ld-2.7.so) ==25938== by 0x4003C0E: (within /lib/ld-2.7.so) ==25938== by 0x4013C14: (within /lib/ld-2.7.so) ==25938== by 0x4001318: (within /lib/ld-2.7.so) ==25938== by 0x4000A67: (within /lib/ld-2.7.so) ==25938== ==25938== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) ==25938== malloc/free: in use at exit: 0 bytes in 0 blocks. ==25938== malloc/free: 0 allocs, 0 frees, 0 bytes allocated. ==25938== For counts of detected errors, rerun with: -v ==25938== All heap blocks were freed -- no leaks are possible. zsh: illegal hardware instruction valgrind ./a.out
不正な命令って? なんだかおかしい.
でもこれは実は心配なくて, valgrind が新しめの命令に対応していないだけらしい. aptitude install valgrind/testing したら大丈夫になった.