Oracle Solaris Studio 12.4 Man Pages

印刷ビューの終了

更新: January 2015
 
 

discover(1)

名前

discover - メモリーエラー検出ツール

形式

 discover [-?] [-h] [-a] [-b browser] [-c [- | lib [:scope...]| file] [-D dir] [-e num] [-E num] [-f] [-F [parent|child|both]] [-H html_file] [-i] [-k] [-K] [-l] [-m] [-n] [-N lib] [-o file] [-s] [-S num] [-T] [-v] [-V] [-w txt_file] target[:scope] 

説明

メモリーエラー検出ツール (Discover) は、実行時のプログラムメモリーの割り当てや使用に関連したプログラミングエラーを検出するためにソフトウェア開発者によって使用されるツールです。

Discover によって検出されるエラーの例には、次のものがあります。

  • 非初期化メモリーへのアクセス

  • 非割り当てメモリーからの読み取り、および非割り当てメモリーへの書き込み

  • 割り当て済み配列範囲外のメモリーへのアクセス

  • 解放済みメモリーの使用

  • 不正なメモリーブロックの解放

  • メモリーリーク

実行可能ファイルの準備、計測、および実行の簡単な例を次に示します。

 
% cc -g -O2 test.c -o test.prep
% discover -w - -o test.disc test.prep
% ./test.disc
ERROR (UMR): accessing uninitialized data from address 0x5000c
(4 bytes) at:
     foo() + 0xdc  <ui.c:6>
          3:    int *t;
          4:    foo() {
          5:     t = malloc(5*sizeof(int));
          6:=>   printf("%d0, t[1]);
          7:    }
          8:
          9:    main()
     main() + 0x1c
     _start() + 0x108
    block at 0x50008 (20 bytes long) was allocated at:
     malloc() + 0x260
     foo() + 0x24  <ui.c:5>
          2:
          3:    int *t;
          4:    foo() {
          5:=>   t = malloc(5*sizeof(int));
          6:     printf("%d0, t[1]);
          7:    }
          8:
     main() + 0x1c
     _start() + 0x108

***************** Discover Memory Report *****************

1 block at 1 location left allocated on heap with a total size of
20 bytes

    1 block with total size of 20 bytes
     malloc() + 0x260
     foo() + 0x24  <ui.c:5>
          2:
          3:    int *t;
          4:    foo() {
          5:=>   t = malloc(5*sizeof(int));
          6:     printf("%d0, t[1]);
          7:    }
          8:
     main() + 0x1c
     _start() + 0x108

DISCOVER SUMMARY:
     unique errors   : 1 (1 total, 0 filtered)
     unique warnings : 0 (0 total, 0 filtered)

Discover を使用するには、Sun Studio 12 Update 1、Oracle Solaris Studio 12.2 以降のアップデートのコンパイラ、または Oracle Solaris 10 update 6 以降のアップデート (または Oracle Solaris 11 Express) を搭載したマシンで Oracle Solaris Systems 4.2.0 以降用の GCC を使用して、入力バイナリをコンパイルする必要があります。それ以前の OS では、-xbinopt=prepare フラグを試してください (SPARC プラットフォームのみ)。-g オプションを使用すると、より情報に富んだメッセージを Discover で生成できます。Discover は、-xlinkopt を使用してコンパイルされたバイナリと互換性がありません。

メッセージ

メッセージ

Discover は、次のエラーメッセージを生成できます。

 
ERROR (UAR) reading from unallocated memory
ERROR (UAW) writing to unallocated memory
ERROR (FMR) reading from freed memory
ERROR (FMW) writing to freed memory
ERROR (UMR) accessing uninitialized data
ERROR (PIR) accessing partially initialized data
ERROR (ABR) reading memory beyond array bounds
ERROR (ABW) writing to memory beyond array bounds
ERROR (DFM) double freeing memory
ERROR (BFM) freeing wrong memory block
ERROR (BRP) bad address parameter for realloc
ERROR (SBR) read is beyond current stack bounds
ERROR (SBW) write is beyond current stack bounds
ERROR (IMR) read from invalid memory address
ERROR (IMW) write to invalid memory address
ERROR (FRP) freed pointer passed to realloc
ERROR (CGB) corrupted array guard block
ERROR (OLP) overlapping source and destination
WARNING (AZS) allocating zero size memory block
WARNING (NAR) non-annotated read
WARNING (NAW) non-annotated write
WARNING (SMR) speculative memory read
WARNING (UFR) unknown stack frame read
WARNING (UFW) unknown stack frame write
WARNING (USR) unknown status while reading
WARNING (USW) unknown status while writing

オプション

次のオプションがサポートされています。

?
-h

Print help message.

-a

コードアナライザで使用するためにエラーデータを binary_name.analyze/dynamic ディレクトリに書き込みます。

-b browser

計測機構の組み込まれたプログラムを実行するとき、Web ブラウザ browser を自動的に起動します (デフォルトでは off)。

-c [- | lib [:scope...]| file]

すべてのライブラリ、lib、または file に (新しい行で区切って) 示されているライブラリ内のエラーを検査します。デフォルトでは、ライブラリ内のエラーを検査しません。

コロンで区切られたファイルまたはディレクトリを追加することによって、ライブラリの検査のスコープを制限します。scope には、ELF ファイルまたはディレクトリを指定できます。ELF ファイルが指定されている場合は、そのファイルで定義されているすべての関数が検査されます。ディレクトリが指定されている場合は、そのディレクトリ内のすべてのファイルが再帰的に使用されます。たとえば、-c libt.so:/abc/t1.o:t2.o:dir は、/abc/t1.ot2.o、および dir の下に存在するすべての ELF ファイルで定義されている関数についてのみライブラリ libt.so を検査します。ライブラリが -c ファイルオプションを使用したリストである場合は、そのリスト内の任意の行に scope を追加できます。

-D dir

キャッシュディレクトリ。デフォルトは $HOME/SUNW_Bit_Cache です。

-e n

レポートに n メモリーエラーのみを表示します (デフォルトでは、すべてのエラーを表示します)。

-E n

レポート内の n 個のメモリーリークのみを表示します (デフォルトは 100 です)。

-f

レポート内のオフセットを表示します (デフォルトでは非表示です)。

-F [parent | child | both]

Discover で計測したバイナリがその実行中にフォークした場合の動作を決定します。デフォルトでは、Discover は引き続き、親プロセスと子プロセスの両方からメモリーアクセスエラーのデータを収集します。Discover が親プロセスにのみ従うようにする場合は、-F parent を指定します。Discover が子プロセスにのみ従うようにする場合は、-F child を指定します。

-H html_file

分析を HTML ファイルに出力します。html_file が相対パス名である場合は、計測されたバイナリが実行されている作業ディレクトリを基準にして配置されます。ファイル名に %p が含まれている場合、そのファイル名はプロセス ID に置き換えられます。詳細は、-w を参照してください。

-i

データの競合を検出するために計測します。Oracle Studio スレッドアナライザのドキュメントを参照してください。

-k

強制的に再計測します。

-K

bit.rc 初期化ファイルを読み取りません。

-l

Discover を簡易モードで実行します。プログラムの実行は速くなりますが、検出されるエラーの数が制限されます。入力バイナリを特別に準備する必要はありません。

-m

レポート内の符号化された名前を表示します (デフォルトでは非表示です)。

-n

実行可能ファイルのエラーを検査しません。デフォルトでは、実行可能ファイル内のエラーを検査します。

-N lib

lib を無視します。

-o file

計測された出力ファイル名。

-s

依存するライブラリが計測不可能であってもかまいません。

-S n

レポートに n スタックフレームのみを表示します (デフォルトは 8 です)。

-T

実行時にライブラリを計測しません。

-v

冗長。

-V

バージョンを出力し、それ以上の処理を行わずに終了します。

-w txt_file

Discover の分析をテキストファイルに書き込みます。stderr を指定するには、「-」を使用します。txt_file が相対パス名である場合は、計測されたバイナリが実行されている作業ディレクトリを基準にして配置されます。Discover のランタイムにファイルの名前にプロセス ID を追加するよう指示することによって、プロセス固有のファイル名にすることができます。これは、ファイル名に %p 文字列を追加することによって実行できます。たとえば、-w report.%p.txt フラグは、report.process_ID.txt というファイルを生成します。ファイル名に %p マクロが複数含まれている場合は、最初のマクロだけが置き換えられます。

target[:scope]

コロンで区切られたファイルまたはディレクトリを追加することによって、検査のターゲットのスコープを制限します。scope には、ELF ファイルまたはディレクトリを指定できます。ELF ファイルが指定されている場合は、そのファイルで定義されているすべての関数が検査されます。ディレクトリが指定されている場合は、そのディレクトリ内のすべてのファイルが再帰的に使用されます。たとえば、a.out:/abc/t1.o:t2.o:dir は、/abc/t1.ot2.o、および dir の下に存在するすべての ELF ファイルで定義されている関数についてのみターゲット a.out を検査します。

使用法

Discover は、-w txtfile オプションを使用してテキストレポートを生成するか、-H html_file オプションを使用して HTML レポートを生成するか、または両方のオプションが使用されている場合はその両方を生成できます。

どちらのオプションも使用されていない場合、デフォルトの出力は HTML ファイル outfile.html です。ここで、outfile は計測された出力ファイルのベース名です。このファイルは、計測されたバイナリが実行されている作業ディレクトリ内に配置されます。

終了ステータス

次の終了値が返されます。

0

入力ファイルはすべて正常に出力されました。

1

エラーが発生しました。

環境変数

SUNW_DISCOVER_OPTIONS

この環境変数を Discover のフラグのリスト (-a-b-e-E-f-F-H-l-L-m-S-w) に設定することによって、計測されるバイナリの実行時動作を変更できます。たとえば、報告されるエラーの数を 50 に変更し、レポート内のスタックの深さを 3 に制限する場合は、SUNW_DISCOVER_OPTIONS を「-E 50 -S 3」に設定してください。

使用例 1 出力を HTML ファイルに送信します。

デフォルトでは、Discover は出力を HTML ファイルに送信します。

 
% cat dtest_2.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
    char *cp;
    cp = (char *)malloc(10);
    cp[11] = 't';
    return 0;
}

% cc -g -O1 -o dtest_2.prep dtest_2.c
% discover -o dtest_2.disc dtest_2.prep
% ./dtest_2.disc
% ls
dtest_2.c
dtest_2.prep*
dtest_2.disc*
dtest_2.disc.html

Discover はメッセージを出力しませんでしたが、サマリーおよびクリックして詳細を表示する使いやすいインタフェースを提供する HTML ファイルを生成しことに注意してください。

使用例 2 レポートをテキスト形式で stderr に出力します。

この例では、使用するプログラムは例 #1 と同じですが、「-w -」オプションを使用してレポートをテキスト形式で stderr に出力します。

% discover -w - -o dtest_2.disc dtest_2.prep
% ./dtest_2.disc
ERROR (ABW): writing to memory beyond array bounds at address 0x50013 (1 byte) at:
     main() + 0x138  <dtest_2.c:7>
           4:    {
           5:        char *cp;
           6:        cp = (char *)malloc(10);
           7:=>      cp[11] = 't';
           8:        return 0;
           9:    }
     _start() + 0x108
    block at 0x50008 (10 bytes long) was allocated at:
     malloc() + 0x260
     main() + 0x94  <dtest_2.c:6>
          3:    int main(int argc, char *argv[])
          4:    {
          5:        char *cp;
          6:=>      cp = (char *)malloc(10);
          7:        cp[11] = 't';
          8:        return 0;
          9:    }
     _start() + 0x108

***************** Discover Memory Report *****************

1 block at 1 location left allocated on heap with a total size of 
10 bytes

    1 block with total size of 10 bytes
     malloc() + 0x260
     main() + 0x94  <dtest_2.c:6>
          3:    int main(int argc, char *argv[])
          4:    {
          5:        char *cp;
          6:=>      cp = (char *)malloc(10);
          7:        cp[11] = 't';
          8:        return 0;
          9:    }
     _start() + 0x108

DISCOVER SUMMARY:
     unique errors   : 1 (1 total, 0 filtered)
     unique warnings : 0 (0 total, 0 filtered)
          
           
使用例 3 初期化されていないデータの使用を含むプログラムを検査します。

この例では、初期化されていないデータの使用を含むプログラムを検査します。

 
% cat dtest_3.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
    char s[10];
    printf("s[1] = %d\n",s[1]);
    return 0;
}

% cc -g -O1 -o dtest_3.prep dtest_3.c
% ./dtest_3.prep
s[1] = 5

% discover -w - -o dtest_3.disc dtest_3.prep
% ./dtest_3.disc
ERROR (UMR): accessing uninitialized data from address 0xffbff023
(1 byte) at:
        main() + 0x4c [dtest_3.disc:0x3004c]
          <dtest_3.c:7>:
                 4:    int main(int argc, char *argv[])
                 5:    {
                 6:        char s[10];
                 7:=>      printf("s[1] = %d\n",s[1]);
                 8:        return 0;
                 9:    }
                10:
        _start() + 0x108 [dtest_3.disc:0x107cc]
s[1] = 5

***************** Discover Memory Report *****************
No allocated memory left on program exit.
DISCOVER SUMMARY:
        unique errors   : 1 (1 total)
        unique warnings : 0 (0 total)

要件

要件

オペレーティングシステムの要件

Discover ソフトウェアは、Oracle Solaris バージョン 10 update 6 以降のアップデートおよび Oracle Solaris 11 Express 上で動作します。

コンパイラの要件

Discover ソフトウェアは、Sun Studio 12 Update 1 コンパイラ、Oracle Solaris Studio 12.2、Oracle Solaris Studio 12.3、または Oracle Solaris Studio 13 でコンパイルされたバイナリでのみ動作します。上記のようにコンパイルされていないバイナリ上で Discover を実行しようとすると、Discover はエラーを発行し、バイナリを計測しません。バイナリの構築時に -g オプションを使用することが強く推奨されます。-g オプションを使用しない場合、Discover は、エラーや警告を報告するときにソースコードと行番号の情報を表示しません。代わりに、それほど役に立たない可能性のある、対応する機械レベルの命令のプログラムカウンタ (PC) だけを表示します。また、-g オプションを使用すると、Discover ソフトウェアがより正確な結果を生成するのにも役立ちます。-xlinkopt フラグでコンパイルされたバイナリは、Discover と互換性がありません。

共有ライブラリの計測

Discover は、すべての共有ライブラリを含む、プログラム全体が計測された場合にもっとも正確な結果を生成します。デフォルトでは、Discover は実行可能ファイルのメモリーエラーだけを検査して報告します。Discover のランタイムは、リンカーの監査インタフェース (rtld-audit とも呼ばれます) または LD_AUDIT 環境変数を使用して、計測される共有ライブラリを Discover のキャッシュディレクトリから自動的にロードします。Oracle Solaris では、監査インタフェースはデフォルトで使用されます。Linux では、計測されるバイナリの実行中に、コマンド行で LD_AUDIT を設定する必要があります。

Oracle Linux 上の 32 ビットアプリケーションの場合は、次を使用します。

% LD_AUDIT=/compiler/prod/lib/postopt/bitdl.so a.out

Oracle Linux 上の 64 ビットアプリケーションの場合は、次を使用します。

% LD_AUDIT=/compiler/prod/lib/postopt/amd64/bitdl.so a.out

このメカニズムは、Oracle Enterprise Linux 5.x の稼働するすべての環境で動作するとはかぎりません。ライブラリ計測が不要で、LD_AUDIT が設定されていない場合、Oracle Enterprise Linux 5.x 上の Discover には問題はありません。バイナリの正しい準備の詳細は、『Oracle Solaris Studio: Discover および Uncover ユーザーズガイド』を参照してください。

ファイル

Discover と Bit .rc ファイル

Discover は、起動時に一連の .rc ファイルを読み取ることによってその状態を初期化します。システムファイル compiler_area/prod/lib/postopt/bit.rc は、特定の変数のデフォルト値を提供します。Discover は最初にこのファイル、次に $HOME/.bit.rc (存在している場合)、次に `pwd`/.bit.rc (存在している場合) を読み取ります。

.rc ファイルには、変数の set、変数への append、および変数からの remove を実行するコマンドが含まれています。set コマンドが存在する場合は常に、変数の以前の値 (存在する場合) が破棄されます。append コマンドにより、その引数が変数の既存の値に (コロンセパレータのあとに) 付加されます。remove コマンドにより、その引数が変数の既存の値から (コロンセパレータとともに) 削除されます。

.rc ファイルで設定されている変数には、計測時に無視するライブラリのリストや、バイナリ内の注釈が付いていないコードの割合を計算するときに無視する関数または関数接頭辞のリストが含まれます。

詳細は、.rc システムファイル内のヘッダーを参照してください。

関連項目

code-analyzer (1) , CC (1) , cc (1) , f77 (1) , f90 (1) , f95 (1) , gcc(1), bit (3F)