実行時検査を使用するには、使用したい検査の種類を指定します。
メモリー使用状況とメモリーリークの検査を有効にするには、次のコマンドを使用します。
(dbx) check -memuse
メモリー使用状況検査またはメモリーリーク検査が有効になっている場合、showblock コマンドは、指定されたアドレスにあるヒープブロックに関する詳細情報を表示します。 この詳細情報では、ブロックの割り当て場所とサイズを知ることができます。詳細については、showblock コマンドを参照してください。
メモリーアクセス検査のみを有効にするには、次のコマンドを使用します。
(dbx) check -access
メモリーリーク検査、メモリー使用状況検査、およびメモリーアクセス検査を有効にするには、次のコマンドを使用します。
(dbx) check -all
詳細については、check コマンドを参照してください。
実行時検査を完全に無効にするには、次のコマンドを使用します。
(dbx) uncheck -all
詳細については、uncheck コマンドを参照してください。
必要な種類の実行時検査を有効にしたら、ブレークポイントを使用して、または使用しないでテスト対象のプログラムを実行します。
プログラムは正常に動作しますが、各メモリーアクセスが実行される直前にその妥当性がチェックされるため、動作速度は遅くなります。無効なアクセスを検出すると、dbx はそのエラーの種類と場所を表示します。dbxenv 変数 rtc_auto_continue が on に設定されていないかぎり、制御がユーザーに戻されます。
次に、dbx コマンドを実行します。where コマンドでは現在のスタックトレースを呼び出すことができます。また print を実行すれば変数を確認できます。そのエラーが致命的エラーでない場合は、cont コマンドを使用してプログラムの実行を継続できます。 プログラムは次のエラーまたはブレークポイントまで、どちらか先に検出されるところまで実行されます。詳細については、cont コマンドを参照してください。
rtc_auto_continue dbxenv 変数が on に設定されている場合、実行時検査では自動的に、引き続きエラーを検索して実行を継続します。エラーは、dbxenv 変数 rtc_error_log_file_name で指定されたファイルにリダイレクトされます。デフォルトのログファイル名は、/tmp/dbx.errlog.unique-ID です。
suppress コマンドを使用して、実行時検査エラーの報告を制限できます。 詳細については、suppress コマンドを参照してください。
次の単純な例は、hello.c と呼ばれるプログラムに対するメモリーアクセス検査とメモリー使用状況検査を有効にする方法を示しています。
% cat -n hello.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 char *hello1, *hello2;
6
7 void
8 memory_use()
9 {
10 hello1 = (char *)malloc(32);
11 strcpy(hello1, "hello world");
12 hello2 = (char *)malloc(strlen(hello1)+1);
13 strcpy(hello2, hello1);
14 }
15
16 void
17 memory_leak()
18 {
19 char *local;
20 local = (char *)malloc(32);
21 strcpy(local, "hello world");
22 }
23
24 void
25 access_error()
26 {
27 int i,j;
28
29 i = j;
30 }
31
32 int
33 main()
34 {
35 memory_use();
36 access_error();
37 memory_leak();
38 printf("%s\n", hello2);
39 return 0;
40 }
% cc -g -o hello hello.c
% dbx -C hello
Reading ld.so.1
Reading librtc.so
Reading libc.so.1
Reading libdl.so.1
(dbx) check -access
access checking - ON
(dbx) check -memuse
memuse checking - ON
(dbx) run Running: hello
(process id 18306)
Enabling Error Checking... done
Read from uninitialized (rui):
Attempting to read 4 bytes at address 0xeffff068
which is 96 bytes above the current stack pointer
Variable is ’j’
Current function is access_error
29 i = j;
(dbx) cont
hello world
Checking for memory leaks...
Actual leaks report (actual leaks: 1 total size: 32 bytes)
Total Num of Leaked Allocation call stack
Size Blocks Block
Address
========== ====== ========== =======================================
32 1 0x21aa8 memory_leak < main
Possible leaks report (possible leaks: 0 total size: 0 bytes)
Checking for memory use...
Blocks in use report (blocks in use: 2 total size: 44 bytes
Total % of Num of Avg Allocation call stack
Size All Blocks Size
========== ==== ====== ====== =======================================
32 72% 1 32 memory_use < main
12 27% 1 12 memory_use < main
execution completed, exit code is 0関数 access_error() は、初期化される前の変数 j を読み取ります。実行時検査では、このアクセスエラーを「非初期化領域からの読み取り」(rui) エラーとして報告します。
関数 memory_leak() は、戻る前に変数 local を解放しません。memory_leak() が終了してしまうと、local がスコープ外になり、行 20 で確保したブロックがリークになります。
このプログラムは、常にスコープ内にある大域変数 hello1 と hello2 を使用しています。これらの変数はいずれも、使用中ブロック (biu) として報告される割り当て済みメモリーを動的に指します。