Uncover は、Solaris 10 5/08 オペレーティング システム、またはそれ以降の Solaris 10 update を実行している SPARC ベースまたは x86 ベースのシステム上の少なくとも -O1 最適化オプションを使用した、Sun Studio 12 Update 1、Oracle Solaris Studio Express 6/10、Oracle Solaris Studio 12.2 コンパイラ、または GCC for Sun Systems 4.2.0 以降のコンパイラを使用してコンパイルされたバイナリ上で機能します。
上記のようにコンパイルされるバイナリには、Uncover がカバレージデータの収集用に計測するためにバイナリを確実に逆アセンブリする情報が含まれています。
-g オプションを使用して、バイナリのコンパイル時にデバッグ情報を生成することにより、Uncover はソースコードレベルのカバレージ情報を使用できます。バイナリが -g オプションを使用してコンパイルされない場合、プログラムカウンタ (PC) ベースのカバレージ情報のみを使用します。
Uncover を使用してカバレージ情報を生成するには、3 ステップのプロセスがあります。
バイナリの計測
計測済みバイナリの実行
カバレージレポートの生成と表示
入力バイナリは、実行可能ファイルまたは共有ライブラリとすることができます。分析したいバイナリの計測は個別に行う必要があります。
uncover コマンドを使用してバイナリを計測します。たとえば、次のコマンドは、バイナリ a.out を計測し、入力 a.out を計測済み a.out で上書きします。また、このコマンドは、接尾辞 .uc を持つディレクトリ (この場合は a.out.uc) を作成します。この中に、カバレージデータが収集されます。入力バイナリのコピーはこのディレクトリに保存されます。
uncover a.out |
-d directory カバレージデータディレクトリを directory に作成するよう Uncover に指示することができます。このオプションは、複数のバイナリ用のカバレージデータを収集する場合に役立ち、カバレージデータディレクトリのすべてが同じディレクトリ内に作成されるようにします。また、異なる場所から同じ計測済みバイナリの異なるインスタンスを実行する場合、このオプションを使用すると、これらの実行のすべてから取得されるカバレージデータが同じカバレージデータディレクトリに確実に蓄積されるようになります。
-d オプションを使用しない場合、カバレージデータディレクトリは現在の実行ディレクトリに作成されます。
すでに計測されている入力バイナリ上で uncover コマンドを実行する場合、Uncover はすでに計測されているためバイナリを計測できないことと、そのバイナリを実行してカバレージデータを生成できることを伝えるエラーメッセージを発行します。
バイナリを計測した後で、それを正常に実行できます。計測済みバイナリを実行するたびに、コードカバレージデータは、Uncover が計測中に作成した .uc 接尾辞を持つカバレージデータディレクトリに収集されます。Uncover データコレクションは、マルチスレッドおよびマルチプロセスに対して安全であるため、プロセスの同時実行またはスレッド数に制限はありません。カバレージデータは実行およびスレッドのすべてにわたって蓄積されます。
カバレージレポートを生成するには、カバレージデータディレクトリ上で uncover コマンドを実行します。次に例を示します。
uncover a.out.uc |
このコマンドは、a.out.uc ディレクトリのカバレージデータから binary_name.er と呼ばれる Oracle Solaris Studio パフォーマンスアナライザ実験ディレクトリを生成し、パフォーマンスアナライザ GUI を起動して、実験を表示します。現作業ディレクトリまたはホームディレクトリに .er.rc ファイル (『Oracle Solaris Studio 12.2 パフォーマンスアナライザ』のマニュアルを参照) がある場合は、アナライザが実験を表示する方法に影響を及ぼす場合があります。
また、uncover コマンドオプションを使用すると、レポートを HTML 形式で生成して Web ブラウザで表示したり、ASCII 形式で生成して端末ウィンドウで表示したりすることができます。
カバレージレポートのための実験ディレクトリを生成し、パフォーマンスアナライザ GUI で実験を表示します。デフォルトではオンになっています。
カバレージデータを指定のディレクトリに HTML 形式で保存し、それを Web ブラウザで自動的に表示します。デフォルトでオフになっています。
ヘルプ。
カバレージレポートを生成しますが、パフォーマンスアナライザや Web ブラウザなどのビューアを起動しません。
指定されたファイルで ASCII カバレージレポートを生成します。デフォルトでオフになっています。
Uncover バージョンを出力して終了します。
冗長。Uncover が実行する内容のログを出力します。
出力形式は 1 つだけ有効になるため、複数の出力オプションを指定する場合、Discover はコマンドの最後のオプションを使用します。
uncover a.out |
このコマンドは、バイナリ a.out を計測し、入力 a.out を上書きして、現作業ディレクトリに a.out.uc カバレージデータディレクトリを作成し、a.out.uc ディレクトリに入力 a.out のコピーを保存します。a.out がすでに計測されている場合、警告メッセージが表示され、計測は実行されません。
uncover -d coverage a.out |
このコマンドは、a.out.uc カバレージディレクトリをディレクトリ coverage に作成する点を除いて、最初の例が行うすべてのことを実行します。
uncover a.out.uc |
このコマンドは、a.out.uc カバレージディレクトリのデータを使用して、作業ディレクトリにコードカバレージの実験 (a.out.er) を作成し、パフォーマンスアナライザ GUI を起動してその実験を表示します。
uncover -H a.out.html a.out.uc |
このコマンドは、a.out.uc カバレージディレクトリのデータを使用して、ディレクトリ a.out.html に HTML コードカバレージレポートを作成し、Web ブラウザにレポートを表示します。
uncover -t a.out.txt a.out.uc |
このコマンドは、a.out.uc カバレージディレクトリのデータを使用して、ファイル a.out.txt に ASCII コードカバレージレポートを作成します。
デフォルトでは、カバレージディレクトリ上の uncover コマンドを実行する場合、カバレージレポートが Oracle Solaris Studio パフォーマンスアナライザの実験として開かれます。アナライザは、「関数 (Functions)」、「ソース (Source)」、「逆アセンブリ (Disassembly)」、および「命令頻度 (Inst-Freq)」タブを使用して、カバレージデータを表示します。
アナライザでカバレージレポートを開くと、「関数 (Functions)」タブが選択されます。このタブには、関数ごとの「カバレージ外 (Uncoverage)」、「関数カウント (Function Count)」、「命令の実行 (Instr Exec)」、「カバーされているブロックの割合 (%) (Block Covered %)」、「カバーされている命令の割合 (%) (Instr Covered %)」カウンタを一覧表示した列が表示されます。列ヘッダーをクリックすると、どの列でもデータのソートキーとして指定できます。列ヘッダーの矢印をクリックすると、ソート順が逆になります。
「カバレージ外 (Uncoverage)」メトリックは、Uncover の非常に強力な機能です。この列を降順のソートキーとして使用する場合、最上部に表示される関数は、カバレージを増やす可能性が最も高い関数です。例では、main() 関数が「カバレージ外 (Uncoverage)」列で最大数を持つため、リストの最上部に表示されます。(sigprof() および sigprofh() 関数は同数を持つため、アルファベット順に一覧表示されます。)
main() 関数のカバレージ外の数は、関数が呼び出される原因となるスイートにテストが追加される場合に潜在的にカバーされる可能性のあるコードのバイト数です。カバレージが実際に増加する量は、関数の構造によって異なります。関数に分岐がなく、呼び出すすべての関数が直線関数でもある場合、カバレージは実際には定められたバイト数により増加します。ただし、一般的に、カバレージの増加は潜在的に想定されるよりおそらくずっと少ないです。
「カバレージ外 (Uncoverage)」列の 0 以外の値を持つカバーされていない関数は、カバーされていないルート関数と呼ばれ、カバーされている関数によってすべて呼び出されることを意味します。カバーされていない非ルート関数によってのみ呼び出される関数は、独自のカバレージ外の数を持ちません。テストスイートは、潜在性の高いカバーされていない関数をカバーするように改良されるにつれて、これらの関数は、後続の実行で、カバーされるか、またはカバーされないことが明らかにされると想定されます。
カバレージ数は排他的ではありません。
関数カウントは関数が呼び出された回数ですが、カバレージ分析のコンテキストでは、実際の数は重要ではありません。重要なことは数が 0 か 0 以外であるかということです。数が 0 の場合、関数はカバーされません。数が 0 以外の場合、関数はカバーされます。関数の命令が実行される場合、関数はカバーされるとみなされます。
この列で、トップレベル以外のカバーされていない関数を検出できます。ある関数の関数カウントが 0 で、カバレージ外の数も 0 である場合、関数はトップレベルのカバーされている関数ではありません。
「命令の実行 (Instr Exec)」カウンタには、動的な命令カウントが表示されます。「関数 (Functions)」タブに、関数ごとに実行される命令の総数が表示されます。このカウンタは、「ソース (Source)」タブ (「「ソース」タブ」を参照) および「逆アセンブリ (Disassembly) タブ (「「逆アセンブリ」タブ」を参照) にも表示されます。
関数ごとに、「カバーされているブロックの割合 (%) (Block Covered %)」カウンタに、カバーされている関数の基本的なブロックの割合が表示されます。この数により、関数がいかに適切にカバーされているかがわかります。<Total> 行のこの数は無視してください。これは列のパーセンテージの合計であり、意味がありません。
関数ごとに、「カバーされている命令の割合 (%) (Instr Covered %)」カウンタに、カバーされている関数の命令の割合が表示されます。この数によっても、関数がいかに適切にカバーされているかがわかります。<Total> 行のこの数は無視してください。これは列のパーセンテージの合計であり、意味がありません。
バイナリを -g オプションを使用してコンパイルした場合、「ソース (Souece)」タブにはプログラムのソースコードが表示されます。Uncover はバイナリレベルでプログラムを計測し、最適化してプログラムをコンパイルしているため、このタブのカバレージ情報は解釈するのが困難な可能性があります。
「ソース (Source)」タブの「命令の実行 (Instr Exec)」カウンタには、各ソース行に対して実行される命令の総数が表示され、これは基本的に文レベルのコードカバレージ情報です。0 以外の値は、文がカバーされていることを意味します。0 の値は、文がカバーされていないことを意味します。変数宣言およびコメントには命令の実行カウントがありません。
「ソース (Source)」タブのある行を選択し、次に「逆アセンブリ (Disassembly)」タブを選択する場合、アナライザは、バイナリで選択した行を検出し、その逆アセンブリを表示しようとします。
このタブの「命令の実行 (Instr Exec)」カウンタには、各命令が実行される回数が表示されます。
「命令頻度 (Inst-Freq)」タブにはカバレージの概要全体が表示されます。
カバレージデータディレクトリからカバレージレポートを生成する際に -t オプションを指定する場合、Uncover はカバレージレポートを指定された ASCII (テキストファイル) に書き込みます。
UNCOVER Code Coverage Total Functions: 95 Covered Functions: 58 Function Coverage: 61.1% Total Basic Blocks: 568 Covered Basic Blocks: 258 Basic Block Coverage: 45.4% Total Basic Block Executions: 564,812,760 Average Executions per Basic Block: 994,388.66 Total Instructions: 6,201 Covered Instructions: 3,006 Instruction Coverage: 48.5% Total Instruction Executions: 4,760,934,518 Average Executions per Instruction: 767,768.83 Number of times this program was executed: unavailable Functions sorted by metric: Exclusive Uncoverage Excl. Excl. Excl. Excl. Name Uncoverage Function Block Instr Count Covered % Covered % 13404 6004876 5464 5384 <Total> 1036 0 0 0 main 980 0 0 0 iofile 748 0 0 0 do_vforkexec 732 0 0 0 callso 708 0 0 0 do_forkexec 648 0 0 0 callsx 644 0 0 0 sigprof 644 0 0 0 sigprofh 556 0 0 0 do_chdir 548 0 0 0 correlate 492 0 0 0 do_popen 404 0 0 0 pagethrash 384 0 0 0 so_cputime 384 0 0 0 sx_cputime 348 0 0 0 itimer_realprof 336 0 0 0 ldso 304 0 0 0 hrv 300 0 0 0 do_system 300 0 0 0 do_burncpu 300 0 0 0 sx_burncpu 288 0 0 0 forkcopy 276 0 0 0 masksignals 256 0 0 0 sigprof_handler 256 0 0 0 sigprof_sigaction 216 0 0 0 do_exec 196 0 0 0 iotest 176 0 0 0 closeso 156 0 0 0 gethrustime 144 0 0 0 forkchild 144 0 0 0 gethrpxtime 136 0 0 0 whrlog 112 0 0 0 masksig 92 0 0 0 closesx 84 0 0 0 reapchildren 36 0 0 0 reapchild 32 0 0 0 doabort 8 0 0 0 csig_handler 0 1 66 72 acct_init 0 1 100 100 bounce 0 63 100 96 bounce_a 0 60 100 100 bounce-b 0 16 71 58 check_sigmask 0 1 83 77 commandline 0 1 100 98 cputime 0 1 100 98 dousleep 0 1 100 100 endcases 0 1 100 95 ext_inline_code 0 1 100 96 ext_macro_code 0 1 100 99 fitos 0 2 81 80 get_clock_rate 0 1 100 100 get_ncpus 0 1 100 100 gpf 0 1 100 100 gpf_a 0 1 100 100 gpf_b 0 10 100 93 gpf_work 0 1 100 97 icputime 0 1 100 96 inc_body 0 1 100 96 inc_brace 0 1 100 95 inc_entry 0 1 100 95 inc_exit 0 1 100 96 inc_func 0 1 100 94 inc_middle 0 1 57 72 init_micro_acct 0 1 50 43 initcksig 0 1 100 95 inline_code 0 1 100 95 macro_code 0 1 100 98 muldiv 0 6000000 100 100 my_irand 0 1 100 98 naptime 0 19 50 83 prdelta 0 21 100 100 prhrdelta 0 21 100 100 prhrvdelta 0 1 100 100 prtime 0 552 100 98 real_recurse 0 1 100 100 recurse 0 1 100 100 recursedeep 0 1 100 95 s_inline_code 0 1 100 100 sigtime 0 1 100 95 sigtime_handler 0 19 100 100 snaptod 0 1 100 100 so_init 0 2 66 75 stpwtch_alloc 0 1 100 100 stpwtch_calibrate 0 2 75 66 stpwtch_print 0 2002 100 100 stpwtch_start 0 2000 90 91 stpwtch_stop 0 1 100 100 sx_init 0 1 100 99 systime 0 3 100 95 tailcall_a 0 3 100 95 tailcall_b 0 3 100 95 tailcall_c 0 1 100 100 tailcallopt 0 1 100 97 underflow 0 21 75 71 whrvlog 0 19 100 100 wlog Instruction frequency data from experiment a.out.er Instruction frequencies of /export/home1/synprog/a.out.uc Instruction Executed () TOTAL 4760934518 (100.0) float ops 2383657378 ( 50.1) float ld st 1149983523 ( 24.2) load store 1542440573 ( 32.4) load 882693735 ( 18.5) store 659746838 ( 13.9) ------------------------------------------- Instruction Executed () Annulled In Delay Slot TOTAL 4760934518 (100.0) add 713013787 ( 15.0) 16 1501335 subcc 558774858 ( 11.7) 0 6002 br 558769261 ( 11.7) 0 0 stf 432500661 ( 9.1) 726 36299281 ldf 408226488 ( 8.6) 40 103000396 faddd 391230847 ( 8.2) 0 0 fdtos 366200726 ( 7.7) 0 0 fstod 360200000 ( 7.6) 0 0 lddf 288250336 ( 6.1) 500 282200229 stw 138028738 ( 2.9) 26002 25974065 lduw 118004305 ( 2.5) 71 94000270 ldx 68212446 ( 1.4) 0 2000 stx 68211370 ( 1.4) 7 23532716 fitod 36026002 ( 0.8) 0 0 sethi 36002986 ( 0.8) 0 228 fdtoi 30000001 ( 0.6) 0 0 fdivd 26000088 ( 0.5) 0 0 call 22250348 ( 0.5) 0 0 srl 21505246 ( 0 5) 0 21 stdf 21006038 ( 0.4) 0 0 or 19464766 ( 0.4) 0 10981277 fmuls 6004907 ( 0.3) 0 0 jmpl 6004853 ( 0.1) 0 0 save 6004852 ( 0.1) 0 0 restore 6002294 ( 0.1) 0 6004852 sub 6000019 ( 0.1) 0 0 xor 6000000 ( 0.1) 0 0 fitos 6000000 ( 0.1) 0 0 fstoi 6000000 ( 0.1) 0 0 and 6000000 ( 0.1) 0 0 andn 6000000 ( 0.1) 0 0 sll 3505225 ( 0.1) 0 0 nop 3505219 ( 0.1) 0 3505219 fxtod 7763 ( 0.0) 0 0 bpr 6000 ( 0.0) 0 0 fcmped 4837 ( 0.0) 0 0 fbr 4837 ( 0.0) 0 0 fmuld 2850 ( 0.0) 0 0 orcc 383 ( 0.0) 0 0 sra 241 ( 0.0) 0 0 ldsb 160 ( 0.0) 0 0 mulx 87 ( 0.0) 0 0 stb 31 ( 0.0) 0 0 mov 21 ( 0.0) 0 0 fdtox 15 ( 0.0) 0 0 ========================================================== |
HTML レポートは、パフォーマンスアナライザに表示されるレポートに類似しています。
関数名のリンクまたは関数の trimmed のリンクをクリックする場合、その関数の逆アセンブリデータが表示されます。
ある関数の Caller-callee リンクをクリックする場合、呼び出し元-呼び出し先データが表示されます。
Uncover は 「Uncover を使用するための要件」の説明に従って準備されているコードのみを計測できます。注釈の付いていないコードは、バイナリにリンクされているアセンブリ言語コード、またはそのセクションに示されてるものより古いコンパイラまたはオペレーティングシステムでコンパイルされたモジュールから来ている場合があります。
準備から特別に除外されているのは、asm 文または .il テンプレートを含むアセンブリ言語モジュールおよび関数です。
Uncover は機械コード上で動作します。Uncover は機械命令のカバレージを検出し、このカバレージをソースコードと関連付けます。一部のソースコード文は関連した機械命令を持たないため、Uncover はそのような文のカバレージを報告しないと思われる場合があります。たとえば、次のコードフラグメントを考えみましょう:
#define A 100 #define B 200 ... if (A>B) { ... }
Uncover が if 文の 0 以外の実行数を報告することを期待しても、コンパイラはこのコードを削除する可能性があるため、Uncover は計測中にそれを表示しません。そのため、これらの命令に対してカバレージは報告されません。