Oracle® Solaris Studio 12.4: dbx コマンドによるデバッグ

印刷ビューの終了

更新: 2015 年 1 月
 
 

プログラムの実行

必要な種類の実行時検査を有効にしたら、ブレークポイントを使用して、または使用しないでテスト対象のプログラムを実行します。

プログラムは正常に動作しますが、各メモリーアクセスが実行される直前にその妥当性がチェックされるため、動作速度は遅くなります。無効なアクセスを検出すると、dbx はそのエラーの種類と場所を表示します。dbxenv 変数 rtc_auto_continueon に設定されていないかぎり、制御がユーザーに戻されます。

次に、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 で確保したブロックがリークになります。

このプログラムは、常にスコープ内にある大域変数 hello1hello2 を使用しています。これらの変数はいずれも、使用中ブロック (biu) として報告される割り当て済みメモリーを動的に指します。