このセクションでは、discover 使用時の既知の制限事項について説明します。
discover ユーティリティーでは、バイナリを適切に準備するの説明に従って準備されているコードのみを計測できます。注釈の付いていないコードは、バイナリにリンクされているアセンブリ言語コード、またはそのセクションに示されてるものより古いコンパイラまたはオペレーティングシステムでコンパイルされたモジュールから来ている場合があります。
discover ユーティリティーは、asm 文または .il テンプレートを含むアセンブリ言語モジュールまたは関数を計測できません。
さらに、Oracle Solaris Studio コンパイラでは注釈データがコンパイルされないため、Oracle Solaris Studio 12.4 の C++ 実行時ライブラリには注釈データが含まれていません。–std=c++11 オプションを使用した C++ コンパイラで構築されたプログラムで discover を使用する場合、discover は UMR または PIR エラーを捕捉しません。
discover は機械コード上で動作します。ツールは、ロードやストアなどの機械命令でエラーを検出し、それらのエラーをソースコードと相互に関連付けます。一部のソースコード文には関連付けられている機械命令がないため、discover は明白なユーザーエラーを検出していないように思われる場合があります。たとえば、次の C コードフラグメントを考えてみましょう:
int *p = (int *)malloc(sizeof(int)); int i; i = *p; /* compiler may not generate code for this statement */ printf("Hello World!\n"); return;
p で示されたアドレスに格納された値を読み取ることは、メモリーが初期化されていないため、潜在的なユーザーエラーとなります。ただし、最適化コンパイラは変数 i が使用されていないことを検出するため、メモリーから読み取って i に割り当てる文のコードは生成されません。この場合、discover は非初期化メモリーの使用 (UMR) を報告しません。
コンパイラの生成コードは予測できません。コンパイラが生成するコードは、–On 最適化オプションを含む、使用するコンパイラオプションによって異なるため、discover によって報告されるエラーも異なる可能性があります。たとえば、–O1 最適化レベルで生成されたコードで報告されるエラーは、–O4 最適化レベルで生成されたコードには当てはまらない可能性があります。
プログラムが C++11 標準オプションを使用したコンパイラで構築された場合、discover ツールは、UMR および PIR エラーを検出できません。
システムライブラリは、オペレーティングシステムとともにインストール済みで、計測用に再度コンパイルできません。discover ユーティリティーは、標準の C ライブラリ (libc.so) からの一般的な関数に対するサポートを提供します。つまり、discover はこれらの関数によってどのメモリーにアクセスされ、どのメモリーが変更されるかを認識しています。ただし、アプリケーションがほかのシステムライブラリを使用する場合、discover レポートで擬陽性を検出する可能性があります。擬陽性が報告される場合、コードから discover API を呼び出してそれらを削除できます。
discover ユーティリティーは、malloc()、calloc()、free()、operator new()、および operator delete() などの標準のプログラミング言語メカニズムによって割り当てられている場合にヒープメモリーを検出できます。
アプリケーションが標準の関数とともにカスタムメモリー管理システム (たとえば、malloc() とともに実装されるプール割り当て管理) を使用する場合、discover がリークや解放されたメモリーへのアクセスを正しく報告することは保証されません。
discover ユーティリティーは、次のメモリーアロケータをサポートしていません。
brk(2)() または sbrk(2)() システム呼び出しを直接使用するカスタムヒープアロケータ
バイナリに静的にリンクされた標準のヒープ管理関数
mmap(2)() および shmget(2)() システム呼び出しを使用してユーザーコードから割り当てられたメモリー
sigaltstack(2)() 関数はサポートされていません。
discover が配列範囲の検出に使用するアルゴリズムのため、静的および自動 (ローカル) 配列の自動的な範囲外アクセスエラーは検出できません。ただし、discover は静的な配列範囲外アクセスエラーを検出できます。動的に割り当てられた配列のエラーを検出できます。