Valgrind を簡単なテスト以外の目的で使用してからしばらく経ちましたが、C で記述されたプログラムをデバッグしようとしたときに、よくわからないことに遭遇しました。それが私のコードに問題があるのか、それとも私が知らない「低レベル」の何か。
次のコードが実行されています (データは構造体です)。
...
data = initialise();
setup(data);
printf("Hi2");
evolve(data);
...
セットアップが終了する場所
...
printf("Setup done.\n");
printf("Hi1");
}
しかし、Valgrindが印刷するもの
valgrind --vgdb=yes --track-origins=yes ./a.out config
です(この前はエラーはありません。データのすべてのプリセット値は問題なく正しく印刷されています。)
...
Setup done.
==3886== Use of uninitialised value of size 8
==3886== at 0x402BF2: evolve (generic_evolution.c:25)
==3886== by 0x400AD3: main (main.c:19)
==3886== Uninitialised value was created by a stack allocation
==3886== at 0x400B54: initialise (main.c:28)
==3886==
==3886== Invalid write of size 4
==3886== at 0x7FF0001C0: ???
==3886== by 0x400AD3: main (main.c:19)
==3886== Address 0xae00000007ff0004 is not stack'd, malloc'd or (recently) free'd
==3886==
==3886==
==3886== Process terminating with default action of signal 11 (SIGSEGV)
==3886== General Protection Fault
==3886== at 0x7FF0001C0: ???
==3886== by 0x400AD3: main (main.c:19)
Hi1Hi2
...
この後、evolve からの最初のいくつかの printfs が出力され、プログラムは途中で終了します。Valgrind なしで実行すると、「Setup done.」の直後に segfault でクラッシュし、Hi1 がプライミングされません。さらに、gdb を使用してプログラムを実行し、
bt full
データの内容だけでなく、evolve の最初に宣言された変数も確認できますが、セットアップはまだ "実際" に完了していないように見えます。gdb によると、segfault は、私が見ることができない何かによって引き起こされます (-g; でコンパイルすると、他の変数が正常に表示されます):
Finished setup.
Program received signal SIGSEGV, Segmentation fault.
0x00007fffffffe200 in ?? ()
(gdb) bt full
#0 0x00007fffffffe200 in ?? ()
No symbol table info available.
...
(prints data and variables declared in evolve)
セットアップの最後のprintfがstdoutに出力される前に、進化でエラーが発生したように見える理由を知っている/推測できる人はいますか(そして、正常に実行すると、2つの単純なprintfsの間のような奇妙な場所でsegfaultが発生します) ?