valgrindとdddの練習
IOI2010の試験環境にはvalgrindとdddとgdbがインストールされているので、valgrindとdddをちょっと使ってみた。
こんなソースを用意。
#include <cstdio> #include <vector> using namespace std; int main(int argc, char **argv) { int n = 100; vector<int> v(n); for(int i = 0; i < 2*n; i++) { v[i] = v[i/2] + 10; } return 0; }
コンパイル
#!/usr/bin/make -f CXX = g++ # CXXFLAGS = -O2 -Wall -Wextra -s -static -x c++ -g # IOIのコンパイルオプション CXXFLAGS = -O2 -Wall -Wextra -g -x c++ # デバッグ用オプション LDFLAGS = -lm .PHONY: all all: test1
IOIのコンパイルオプションでは、ライブラリを静的リンクしてシンボルテーブルとリロケーション情報を削除する。
デバッグ用のオプションでは、デバッグ用の情報を埋めこむ。
$ make test1
普通に実行してみる
$ ./test1 *** glibc detected *** ./test1: double free or corruption (!prev): 0x08b0d008 *** ======= Backtrace: ========= (略) ======= Memory map: ======== (略) zsh: abort ./test1
「うわっ…バグっちゃったよ…俺が徹夜して書いたプログラム…もうだめぽ…」
dddを使ってみる
$ ddd ./test1
てけとーに押してブレークポイントを設置
Run!
Contを押すと次のブレークポイントまで行けるなど
で、例えば、ソースコード中のnをダブルクリック
最適化によって消滅したらしい
iをダブルクリックすると何か見える
ちなみにvをダブルクリックするとこんなメッセージが
C++との相性は悪いんかね
さて…残念なことに、エラーが起きているのはv[i]の行ではないことが、必死のマウス連打によってわかってしまった…
valgrindを使ってみる
とりあえずてけとーに
$ valgrind ./test1 ==24191== Memcheck, a memory error detector ==24191== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. ==24191== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info ==24191== Command: ./test1 ==24191== ==24191== Invalid write of size 4 ==24191== at 0x80485CA: main (test1.cpp:9) ==24191== Address 0x42d71b8 is 0 bytes after a block of size 400 alloc'd ==24191== at 0x402569A: operator new(unsigned int) (vg_replace_malloc.c:255) ==24191== by 0x80485A4: main (new_allocator.h:89) ==24191== ==24191== ==24191== HEAP SUMMARY: ==24191== in use at exit: 0 bytes in 0 blocks ==24191== total heap usage: 1 allocs, 1 frees, 400 bytes allocated ==24191== ==24191== All heap blocks were freed -- no leaks are possible ==24191== ==24191== For counts of detected and suppressed errors, rerun with: -v ==24191== ERROR SUMMARY: 100 errors from 1 contexts (suppressed: 17 from 6)
test1.cppの9行目に問題があると一瞬でわかった!すごい!
ちなみに、さらに有用な情報を見るために必要なオプションのヒントがメッセージの最後のほうに書かれることもあるらしい。
これ便利だな…
続かないかも