私は「ハードCを学ぶC」、特に Valgrindの章 に従っています。この章では、Valgrindの動作を示すために、意図的に間違ったプログラムを提供します。
Valgrindの下でエクササイズを実行すると、スタックトレースに行番号が表示されず、エラーの「(メインの下)」だけが表示されます。
私は間違いなく-gフラグでコンパイルしています。
私のValgrindの出力は次のとおりです。
_djb@twin:~/projects/Learning/C$ valgrind ./ex4
==5190== Memcheck, a memory error detector
==5190== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==5190== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
==5190== Command: ./ex4
==5190==
==5190== Use of uninitialised value of size 4
==5190== at 0x4078B2B: _itoa_Word (_itoa.c:195)
==5190== by 0x407CE55: vfprintf (vfprintf.c:1619)
==5190== by 0x40831DE: printf (printf.c:35)
==5190== by 0x4052112: (below main) (libc-start.c:226)
==5190==
==5190== Conditional jump or move depends on uninitialised value(s)
==5190== at 0x4078B33: _itoa_Word (_itoa.c:195)
==5190== by 0x407CE55: vfprintf (vfprintf.c:1619)
==5190== by 0x40831DE: printf (printf.c:35)
==5190== by 0x4052112: (below main) (libc-start.c:226)
==5190==
==5190== Conditional jump or move depends on uninitialised value(s)
==5190== at 0x407CC10: vfprintf (vfprintf.c:1619)
==5190== by 0x40831DE: printf (printf.c:35)
==5190== by 0x4052112: (below main) (libc-start.c:226)
==5190==
==5190== Conditional jump or move depends on uninitialised value(s)
==5190== at 0x407C742: vfprintf (vfprintf.c:1619)
==5190== by 0x40831DE: printf (printf.c:35)
==5190== by 0x4052112: (below main) (libc-start.c:226)
==5190==
I am 0 years old.
I am 68882420 inches tall.
==5190==
==5190== HEAP SUMMARY:
==5190== in use at exit: 0 bytes in 0 blocks
==5190== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==5190==
==5190== All heap blocks were freed -- no leaks are possible
==5190==
==5190== For counts of detected and suppressed errors, rerun with: -v
==5190== Use --track-origins=yes to see where uninitialised values come from
==5190== ERROR SUMMARY: 22 errors from 4 contexts (suppressed: 11 from 6)
_
VirtualBox VMでUbuntu 11.10を使用しています。
助けてくれてありがとう。
更新
main()
から関数を呼び出し、その関数に誤り(初期化されていない変数など)が含まれている場合、その場所へのトレースを取得しますdoその関数はmain()
で呼び出されました。ただし、main()
内のエラーは未指定のままです。例については this paste をご覧ください。
質問で提供した出力には、次の行が含まれています。
==5190== Use --track-origins=yes to see where uninitialised values come from
このメッセージごとに、次のように./ex4
を実行する必要があります。
valgrind --track-origins=yes ./ex4
デバッグ情報を見つけることができないValgrindの問題を回避するには、静的リンクを使用できます。
gcc -static -g -o ex4 ex4.c
Valgrindの出力には、Uninitialised value was created by a stack allocation
のようなメッセージが含まれます。
==17673== Memcheck, a memory error detector
==17673== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==17673== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==17673== Command: ./ex4
...
==17673== Use of uninitialised value of size 4
==17673== at 0x805CA7B: _itoa_Word (in /home/user/ex4)
==17673== by 0x8049D5F: printf (in /home/user/ex4)
==17673== by 0x8048ECD: main (ex4.c:8)
==17673== Uninitialised value was created by a stack allocation
==17673== at 0x8048EFA: bad_function (ex4.c:17)
...
==17673== Use of uninitialised value of size 4
==17673== at 0x805CA7B: _itoa_Word (in /home/user/ex4)
==17673== by 0x8049D5F: printf (in /home/user/ex4)
==17673== by 0x80490BE: (below main) (in /home/user/ex4)
==17673== Uninitialised value was created by a stack allocation
==17673== at 0x8048EBE: main (ex4.c:4)
...
I am -1094375076 years old.
...
I am -1094369310 inches tall.
...
==17673==
==17673== HEAP SUMMARY:
==17673== in use at exit: 0 bytes in 0 blocks
==17673== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==17673==
==17673== All heap blocks were freed -- no leaks are possible
==17673==
==17673== For counts of detected and suppressed errors, rerun with: -v
==17673== ERROR SUMMARY: 83 errors from 21 contexts (suppressed: 0 from 0)
ファイルex4.c
:
1 #include <stdio.h>
2
3 int main()
4 {
5 int age = 10;
6 int height;
7
8 bad_function();
9
10 printf("I am %d years old.\n");
11 printf("I am %d inches tall.\n", height);
12
13 return 0;
14 }
15
16 int bad_function()
17 {
18 int x;
19 printf("%d\n", x);
20 }
Valgrindの出力は理想的ではありません。初期化されていない変数を含むスタックフレーム(関数)を識別しますが、変数の名前は出力しません。
VirtualBoxでLinuxを実行しても、Valgrindには影響しません。
私も-g
フラグを使用してコンパイルしましたが、行番号を取得できませんでした。アプリの.dSYM
ディレクトリを削除し、--dsymutil=yes
オプションを指定してvalgrindを実行すると、最終的に行番号が取得されました。
多くのディストリビューションでは、glibcのデフォルトバージョンにはデバッグシンボルが含まれていません。
Libc6-dbgパッケージをインストールしてみてください。
"-g"でコンパイルする必要があります。 gcc -g test.c -o testその後、valgrind --track-origins = yes --leak-check = full ./test
--dsymutil = yesソリューションを使用してvalgrindを実行すると、Mac OS X専用になります。
ドキュメントによると:
--dsymutil= no | yes [no]このオプションは、Mac OS XでValgrindを実行している場合にのみ関係します。
Mac OS Xは、遅延デバッグ情報(debuginfo)リンクスキームを使用します。 debuginfoを含むオブジェクトファイルが.dylibまたは実行可能ファイルにリンクされている場合、debuginfoは最終ファイルにコピーされません。代わりに、システムが提供するユーティリティであるdsymutilを実行可能ファイルまたは.dylibで実行して、debuginfoを手動でリンクする必要があります。結果の結合されたdebuginfoは、実行可能ファイルまたは.dylibとともにディレクトリに配置されますが、拡張子は.dSYMになります。
ccではなくgccを試してください
ccは行番号を提供しませんが、gccは提供します
私はこの問題を追いかけましたが、他の答えはどれもうまくいきませんでした。出力には正しいシンボルが表示されましたが、行番号はありませんでした。
私の場合、.zdebug圧縮行番号情報を使用している問題のライブラリが原因で、使用していたvalgrindのバージョンは古く、必要なパッチがまだありません[0]。
解決策は、valgrindを最新バージョンにアップグレードすることでした。