Discover レポートは、ソースコードで効果的に自動補完して問題を修正する情報を提供します。
デフォルトでは、レポートは output_file.html に HTML 形式で書き込まれます。output_file は、計測済みバイナリのベース名です。ファイルは、計測済みバイナリを実行する作業ディレクトリに配置されます。
バイナリを計測する際には、-H オプションを使用して、HTML 出力を指定されたファイルに書き込むように要求するか、または -w オプションを使用して、テキストファイルに書き込むように要求できます (「コマンド行オプション」を参照)。
バイナリの計測後に、たとえば、プログラムを後続の実行用に異なるファイルにレポートを書き込みたい場合に、「SUNW_DISCOVER_OPTIONS 環境変数」でレポートの - H および -w オプションの設定を変更できます。
HTML レポート形式では、プログラムの対話型分析が可能です。HTML 形式のデータは、電子メールを使用するか、Web ページ上に配置して、開発者間で容易に共有できます。JavaScript インタラクティブ機能と組み合わせると、Discover のメッセージを検索する便利な方法が提供されます。
「エラー (Errors)」タブ (「「エラー (Errors)」タブの使用法」を参照)、「警告 (Warnings)」タブ (「「警告 (Warnings)」タブの使用法」を参照)、および「メモリーリーク (Memory Leaks) タブ」 (「「メモリーリーク (Memory Leaks)」タブの使用法」を参照) では、エラーメッセージ、警告メッセージ、およびメモリーリークレポートをそれぞれ検索できます。
左側のコントロールパネル (「コントロールパネルの使用法」を参照) では、右側に現在表示されているタブの内容を変更できます。
ブラウザで最初に HTML レポートを開く場合、「エラー (Errors)」タブが選択され、計測済みのバイナリの実行中に検出されたメモリーアクセスエラーのリストが表示されます。
エラーをクリックすると、エラー時のスタックトレースが表示されます。
-g オプションを使用してコードをコンパイルした場合、関数をクリックすることによってスタックトレースの関数ごとのソースコードを表示できます。
「警告 (Warnings)」タブには、起こり得るアクセスエラーの警告メッセージのすべてが表示されます。警告をクリックすると、警告時のスタックトレースが表示されます。コードを -g オプションを使用してコンパイルした場合、関数をクリックすることによって、スタックトレースの関数ごとのソースコードを表示できます。
「メモリーリーク (Memory Leaks)」タブには、下記にリストされているブロック数とともに、最上部にプログラムの実行終了時に割り当てられている残存ブロック総数が表示されます。
ブロックをクリックすると、ブロックのスタックトレースが表示されます。-g オプションを使用してコードをコンパイルした場合、関数をクリックすることによって、スタックトレースの関数ごとのソースコードを表示できます。
エラー、警告、およびメモリーリークのすべてのスタックトレースを表示するには、コントロールパネルの「スタックトレース (Stack Traces)」セクションの「すべて展開 (Expand All)」をクリックします。関数のすべてのソースコードを表示するには、コントロールパネルの「ソースコード (Source Code)」セクションの「すべて展開 (Expand All)」をクリックします。
エラー、警告、およびメモリーリークのすべてのスタックトレースまたはソースコードを非表示にするには、対応する「すべて折りたたむ (Collapse All)」をクリックします。
コントロールパネルの「エラーの表示 (Show Errors)」セクションは、「エラー (Errors)」タブが選択され、表示されるエラーのタイプを制御できる場合に表示されます。デフォルトでは、検出されたエラーのすべてのチェックボックスがオンになっています。エラーのタイプを非表示にするには、チェックボックスをクリックして、チェックマークを外します。
コントロールパネルの「警告の表示 (Show Warnings)」セクションは、「警告 (Warnings )」タブが選択され、表示される警告のタイプを制御できる場合に表示されます。デフォルトで、検出された警告のすべてのチェックボックスがオンになっています。警告のタイプを非表示にするには、チェックボックスをクリックして、チェックマークを外します。
エラーおよび警告の総数を一覧表示するレポートの概要、およびリークしたメモリー量がコントロールパネルの下方に表示されます。
Discover レポートの ASCII (テキスト) 形式は、スクリプトで処理したり、Web ブラウザにアクセスできない場合に適しています。次に示すのは ASCII レポートの例です。
$ a.out ERROR 1 (UAW): writing to unallocated memory at address 0x50088 (4 bytes) at: main() + 0x2a0 <ui.c:20> 17: t = malloc(32); 18: printf("hello\n"); 19: for (int i=0; i<100;i++) 20:=> t[32] = 234; // UAW 21: printf("%d\n", t[2]); //UMR 22: foo(); 23: bar(); _start() + 0x108 ERROR 2 (UMR): accessing uninitialized data from address 0x50010 (4 bytes) at: main() + 0x16c <ui.c:21>$ 18: printf("hello\n"); 19: for (int i=0; i<100;i++) 20: t[32] = 234; // UAW 21:=> printf("%d\n", t[2]); //UMR 22: foo(); 23: bar(); 24: } _start() + 0x108 was allocated at (32 bytes): main() + 0x24 <ui.c:17> 14: x = (int*)malloc(size); // AZS warning 15: } 16: int main() { 17:=> t = malloc(32); 18: printf("hello\n"); 19: for (int i=0; i<100;i++) 20: t[32] = 234; // UAW _start() + 0x108 0 WARNING 1 (AZS): allocating zero size memory block at: foo() + 0xf4 <ui.c:14> 11: void foo() { 12: x = malloc(128); 13: free(x); 14:=> x = (int*)malloc(size); // AZS warning 15: } 16: int main() { 17: t = malloc(32); main() + 0x18c <ui.c:22> 19: for (int i=0; i<100;i++) 20: t[32] = 234; // UAW 21: printf("%d\n", t[2]); //UMR 22:=> foo(); 23: bar(); 24: } _start() + 0x108 ***************** Discover Memory Report ***************** 1 block at 1 location left allocated on heap with a total size of 128 bytes 1 block with total size of 128 bytes bar() + 0x24 <ui.c:9> 6: 7: void bar() { 8: int *y; 9:=> y = malloc(128); // Memory leak 10: } 11: void foo() { 12: x = malloc(128); main() + 0x194 <ui.c:23> 20: t[32] = 234; // UAW 21: printf("%d\n", t[2]); //UMR 22: foo(); 23:=> bar(); 24: } _start() + 0x108 ERROR 1: repeats 100 times DISCOVER SUMMARY: unique errors : 2 (101 total, 0 filtered) unique warnings : 1 (1 total, 0 filtered) |
このレポートはエラーと警告メッセージ、およびその概要で構成されます。
エラーメッセージは、ERROR という単語で開始され、3 文字のコード、ID 番号、およびエラーの説明 (例では、writing to unallocated memory) が含まれます。その他の詳細には、アクセスされたメモリーアドレス、および読み取られた、または書き込まれた数またはバイト数が含まれます。説明の後には、プロセスライフサイクルでエラーの場所を自動補完するエラー時のスタックトレースが表示されます。。
プログラムが -g オプションを使用してコンパイルされた場合、スタックトレースには、ソースファイルおよび行番号が含まれます。ソースファイルにアクセス可能な場合、エラー付近のソースコードが出力されます。各フレームのターゲットソース行は => シンボルによって示されます。
同じバイト数を持つ同じメモリーの場所の同じエラーの種類が繰り返される場合、スタックトレースを含む完全なメッセージが 1 度だけ出力されます。後続のエラーの出現が数えられ、次の例に表示されるように繰り返し数が、複数回発生する同一エラーごとにレポートの末尾に一覧表示されます。
ERROR 1: repeats 100 times |
不正なメモリーアクセスのアドレスがヒープ上にある場合、対応するヒープブロックに関する情報がスタックトレース後に出力されます。その情報には、ブロック開始アドレスとサイズ、およびブロックが割り当てられた時点のスタックトレースが含まれます。ブロックが解放された場合、解放ポイントのスタックトレースも含まれます。
警告メッセージは、WARNINGという単語で開始されている場合を除いて、エラーメッセージと同じ形式で出力されます。概して、これらのメッセージは、アプリケーションの正確さに影響を及ぼさない状態に対して警告しますが、問題を改善するために使用可能な役立つ情報を提供します。たとえば、0 サイズのメモリーを割り当てることは有害ではありませんが、頻繁すぎると、パフォーマンスを低下させる可能性があります。
メモリーリークレポートには、ヒープ上に割り当てられているがプログラムの終了時にリリースされないメモリーブロックに関する情報が含まれます。次に示すのは、メモリーリークレポートの例です。
$ DISCOVER_MEMORY_LEAKS=1 ./a.out ... ***************** Discover Memory Report ***************** 2 blocks left allocated on heap with total size of 44 bytes block at 0x50008 (40 bytes long) was allocated at: malloc() + 0x168 [libdiscover.so:0xea54] f() + 0x1c [a.out:0x3001c] <discover_example.c:9>: 8: { 9:=> int *a = (int *)malloc( n * sizeof(int) ); 10: int i, j, k; main() + 0x1c [a.out:0x304a8] <discover_example.c:33>: 32: /* Print first N=10 Fibonacci numbers */ 33:=> a = f(N); 34: printf("First %d Fibonacci numbers:\n", N); _start() + 0x5c [a.out:0x105a8] ... |
ヘッダーに続く最初の行は、ヒープ上に割り当てられて残されているヒープブロック数とその合計サイズを要約しています。レポートされるサイズは、開発者の見解であり、すなわちメモリーアロケータのブックキーピングのオーバーヘッドは含まれません。
メモリーリークの概要の後に、割り当てポイントのスタックトレースを持つ未解放ヒープブロックごとの詳細情報が出力されます。スタックトレースレポートは、エラーおよび警告メッセージに対して説明されるレポートと同様です。
Discover レポートには概要全体が記載されています。かっこ付きの一意の警告およびエラー数、繰り返しを含むエラーおよび警告の総数を報告します。次に例を示します。
DISCOVER SUMMARY: unique errors : 3 (3 total) unique warnings : 1 (5 total) |