Sun Studio 12: dbx コマンドによるデバッグ

プログラムを実行

目的のタイプの RTC を有効にしてテストするプログラムを実行します。この場合、ブレークポイントを設定してもしなくてもかまいません。

プログラムは正常に動作しますが、それぞれのメモリーアクセスが発生する直前にその妥当性チェックが行われるため、動作速度は遅くなります。無効なアクセスを検出すると、dbx はそのエラーの種類と場所を表示します。 制御はユーザーに戻ります (dbx 環境変数 rct_auto_continueon になっている場合を除く (dbx 環境変数の設定」を参照))。

次に、dbx コマンドを実行します。where コマンドでは現在のスタックトレースを呼び出すことができます。また print を実行すれば変数を確認できます。エラーが致命的でなければ、 cont コマンドでプログラムの処理を続行します。プログラムは次のエラーまたはブレークポイントまで、どちらか先に検出されるところまで実行されます。詳細については、cont コマンド」を参照してください。

rtc_auto_continue 環境変数が on に設定されている場合、RTC はそのままエラーを求めて自動的に続行されます。 検出したエラーは、dbx 環境変数 rtc_error_log_name で指定したファイルにリダイレクトされます (dbx 環境変数の設定」を参照)。デフォルトログファイル名は、/tmp/dbx.errlog.uniqueid です。

RTC エラーの報告が不要な場合は、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
ld.so.1 の読み込み中
librtc.so のシンボル情報を読んでいます
libw.so.1 の読み込み中
libdl.so.1 の読み込み中

(dbx) check -access
アクセス検査 - ON
(dbx) check -memuse
メモリー使用状況検査 - ON
(dbx) run Running: hello
(プロセス id 18306)
実行時検査を有効にしています...done
非初期化領域からの読み取り (rui):
4 バイト読み取りをアドレス 0xeffff068 でしようとしました
               それは 96 バイト現スタックポインタより上です
変数は 'j' です。
現関数: access_error
    29       i = j;
(dbx) cont
hello world
メモリーリーク検査中...
実際のリークの報告    (実際のリーク:        1  合計サイズ:      32 バイト)
 合計      ブロック   リーク     割り当て呼び出しスタック
 サイズ     数      ブロック
                アドレス
==========  ======     ========== =======================================
     32    1    0x21aa8 memory_leak < main

起こり得るリークの報告  (起こり得るリーク:      0  合計サイズ:      0 バイト)
メモリー使用状況検査中...
ブロック使用量の報告   (ブロック使用量:       2  合計サイズ:      44 バイト

 合計     割合   ブロック  平均   割り当て呼び出しスタック
 サイズ    %    数     サイズ
========== ====   ======    ======  =======================================
     32  72%    1    32  memory_use < main
     12  27%    1    12  memory_use < main

実行完了。終了コードは 0 です。

関数 access_error() は、初期化される前の変数 j を読み取ります。RTC は、このアクセスエラーを非初期化領域からの読み取り (rui) として報告します。

関数 memory_leak() は、終了する前に local を解放 (free()) しません。memory_leak() が終了してしまうと、local がスコープ外になり、行 20 で確保したブロックがリークになります。

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