前へ | 次へ | 目次 | 索引 |
ヒープ・アナライザを終了するには,ヒープ・アナライザ画面の「File」メニューで「Exit」を選択します。
12.5 サンプル・セッション
この節では,ヒープ・アナライザの各ウィンドウとメニューから得られる情報をまとめて,ユーザ・アプリケーションにある特定のメモリ・リークを見つける方法の例を示します。
この例では,すでにヒープ・アナライザを起動し,ユーザ・アプリケーションを実行してあると考えます。「Memory Map」ディスプレイをスクロールして戻しながら,ユーザ・アプリケーションが会話型コマンドを呼び出したときに表示されるセグメントに注目します。
12.5.1 会話型コマンドの表示の取り出し
メモリ・リークが生じたのは,会話型コマンド SHOW UNITS を入力したときかもしれません。そこで最初の手順として,「Memory Map」を消去し,このコマンドを再入力してみます。
「Memory Map」を消去して SHOW UNITS コマンドを再入力するには,次の手順に従います。
「Memory Map」内の以前の出力がすべて消去される。
以後の「Memory Map」への出力が,すべて保存される。
小さく表示された一連のセグメントは増分されているらしいが,表示が小さすぎて確認できない。
セグメントのビューが拡大表示される。
それぞれの SCA__MEM_GET_VM セグメントに割り当てられたメモリ空間は,SHOW UNITS コマンドごとに少しずつ増大しています(図 12-12 を参照)。同一サイズのはずの割り当てが増大していることは,メモリ・リークの発生を示しています。
図 12-12 メモリ・リークを示すメモリ割り当ての増分
各セグメントに対応したセグメント・タイプには,SCA__MEM_GET_VM というラベルが付けられています。これはかなり下位レベルでのメモリ管理ルーチンであり,多数のセグメントがこのルーチンを共有しています。次の手順は,セグメント・タイプを再定義して,抽象化レベルをもっと役に立つものにすることです。できればアプリケーションのルーチン名と対応させます。
セグメント・タイプを再定義するには,次の手順に従います。
コンテキスト依存の「Memory Map」ポップアップ・メニューが表示される。
セグメントに対応したセグメント・タイプが,SCA__MEM_GET_VM から,有用な "crl_begin_unit_query" に変更される(図 12-13 を参照)。
図 12-13 セグメント・タイプを再定義する「Do-Not-Use Type」メニュー項目
セグメントを表示する抽象化レベルを決定したら,次は,セグメントが割り当てられたときの呼び出しスタックの状態を調べます。セグメントごとのトレースバックを調べると,セグメントが作成された時点と理由,およびメモリに問題が生じた理由が分かります。
トレースバック情報を表示するには,次の手順に従います。
コンテキスト依存の「Memory Map」ポップアップ・メニューが表示される。
セグメントのトレースバック情報が「Information」ウィンドウに表示される。
セグメントのトレースバックは,crl_begin_unit_query ルーチンが SHOW UNITS コマンド用の環境を設定していることを示しています。このイベントをさらに詳しく調べるには,イベントに対応したソース・コードを表示させます。
ソース・コードを表示するには,crl_begin_unit_query を参照するトレースバック行を MB1 でダブルクリックします。
「Source」ウィンドウにソース・コードが表示されます。crl_begin_unit_query を呼び出しスタックに置いたルーチン呼び出しが強調表示されます(図 12-14 を参照)。
図 12-14 トレースバック・エントリのクリックによる,対応したソース・コードの表示
トレースバック・エントリをアプリケーション・ソース・コードのルーチンと結び付けた後,「Source」ウィンドウを拡大して,ソース・コードの記憶位置で割り当てエラーを探すことができます。
たとえば,図 12-15 では,強調表示されている 5725 行目が unit_query への割り当てを行っています。この割り当ては,別の割り当てが行われる 5740 行目より前で割り当て解除されていません。このコーディング・エラーがメモリ・リークの原因です。
図 12-15 二重の割り当てを示すソース・コード
本章では,デバッガが持つ次の便利な機能について説明します。
デバッガ・コマンド・プロシージャは,ファイルに記述された一連のコマンドです。デバッガがコマンド・プロシージャを実行するよう指定して,デバッグ・セッションを再作成したり,前のセッションを続行したり,デバッグ・セッションの間に同じデバッガ・コマンドを何度も入力しなくてもすむようにしたりできます。コマンド・プロシージャにはパラメータを引き渡すことができます。
DCL コマンド・プロシージャの場合と同様に,デバッガ・コマンド・プロシージャを実行するには,ファイル指定の先頭にアットマーク(@)を付けます。@ はプロシージャ実行コマンドです。
デバッガ・コマンド・プロシージャは,デバッガ初期化ファイル(第 13.2 節 を参照)に指定されているような標準的な設定用デバッガ・コマンドを数多く定期的に実行する場合に特に便利です。また,デバッガ・ログ・ファイルをコマンド・プロシージャとして使用することもできます(第 13.3 節 を参照)。
13.1.1 基本的な規則
次に示すのは,デバッガ・コマンド・プロシージャBREAK7.COMの例です。
! ***** デバッガ・コマンド・プロシージャBREAK7.COM ***** SET BREAK/AFTER:3 %LINE 120 DO(EXAMINE K,N,J,X(K); GO) SET BREAK/AFTER:3 %LINE 160 DO(EXAMINE K,N,J,X(K),S; GO) SET BREAK %LINE 90 |
このコマンド・プロシージャをプロシージャ実行コマンド(@)で実行すると,プロシージャ内に記述されたコマンドがその順番に実行されます。
コマンド・プロシージャへのコマンド入力の規則については,デバッガのオンライン・ヘルプを参照してください(HELP Command_Format と入力します)。
コマンド・プロシージャには,パラメータを引き渡すことができます。パラメータ引き渡しの規則については,第 13.1.2 項 を参照してください。
プロシージャ実行(@)コマンドは,他のデバッガ・コマンドと同様に入力することができます。すなわち,端末から直接入力したり,別のコマンド・プロシージャ内から入力したり,SET BREAK などのコマンドの DO 句から入力したり,画面表示定義の DO 句から入力したりすることができます。
プロシージャ実行(@)コマンドに指定するファイル指定が完全ファイル指定ではない場合,デバッガは SYS$DISK:[]DEBUG.COM をコマンド・プロシージャの省略時のファイル指定とみなします。たとえば,現在の省略時のディレクトリにあるコマンド・プロシージャ BREAK7.COM を実行するためには,次のコマンド行を入力します。
DBG> @BREAK7 |
SET ATSIGN コマンドは,省略時のファイル指定である SYS$DISK:[]DEBUG.COM の一部またはすべてのフィールドの変更を可能にします。SHOW ATSIGN コマンドは,コマンド・プロシージャの省略時のファイル指定を表示します。
省略時の設定では,コマンド・プロシージャから読み込まれたコマンドはエコーバックされません。SET OUTPUT VERIFY コマンドを入力すると,コマンド・プロシージャから読み込まれたすべてのコマンドが,DBG$OUTPUT で指定された現在の出力装置にエコーバックされます。省略時の出力装置は SYS$OUTPUT です。コマンド・プロシージャから読み込まれたコマンドがエコーバックされるかどうかを明らかにするには,SHOW OUTPUT コマンドを使用します。
コマンド・プロシージャ内のコマンドを実行した結果,警告かそれ以上の重大な診断メッセージが表示された場合,そのコマンドは強制終了されます。ただしコマンド・プロシージャの実行は次のコマンド行から続けられます。
13.1.2 コマンド・プロシージャへのパラメータの引き渡し
DCL コマンド・プロシージャの場合と同様に,デバッガ・コマンド・プロシージャにもパラメータを引き渡すことができます。ただし,いくつかの点でその方法が異なります。
ここで説明する規則に従って,ユーザはデバッガ・コマンド・プロシージャに対して必要なだけパラメータを引き渡すことができます。パラメータには,アドレス式,コマンド,または現在使用中の言語で記述された値式を指定できます。コマンド文字列は二重引用符(")で囲み,各パラメータはコンマ(,)で区切らなければなりません。
パラメータが引き渡される側のデバッガ・コマンド・プロシージャには,引き渡された実パラメータと,コマンド・プロシージャ内で宣言された仮パラメータ(シンボル)とを結び付ける DECLARE コマンド行が必要です。
DECLARE コマンドは,コマンド・プロシージャ内でのみ有効です。DECLARE コマンドの構文は次のとおりです。
DECLARE p-name:p-kind[, p-name:p-kind[, ...]] |
それぞれの p-name:p-kind の組み合わせは,仮パラメータ(p-name)をパラメータの種類(p-kind)と関連づけています。有効な p-kind キーワードを次に示します。
ADDRESS | 実パラメータをアドレス式として解釈する |
COMMAND | 実パラメータをコマンドとして解釈する |
VALUE | 実パラメータを現在使用中の言語で記述された値式として解釈する |
次の例は,パラメータがコマンド・プロシージャに引き渡されたとき,どのように処理されるかを示しています。コマンド・プロシージャ EXAM.COM の中の DECLARE K:ADDRESS コマンドは,仮パラメータ K を宣言しています。EXAM.COM に引き渡される実パラメータはアドレス式として解釈されます。EXAMINE K コマンドは,そのアドレス式の値を表示します。SET OUTPUT VERIFY コマンドは,コマンドがデバッガに読み込まれたとき,それらをエコーバックします。
! ***** デバッガ・コマンド・プロシージャEXAM.COM ***** SET OUTPUT VERIFY DECLARE DBG:ADDRESS EXAMINE DBG |
次のコマンド行は,EXAM.COM を実行します。このとき実パラメータ ARR24 を引き渡します。EXAM.COM 内で ARR24 はアドレス式(この場合は配列変数)として解釈されます。
DBG> @EXAM ARR24 %DEBUG-I-VERIFYIC, entering command procedure EXAM DECLARE DBG:ADDRESS EXAMINE DBG PROG_8\ARR24 (1): Mark A. Hopper (2): Rudy B. Hopper (3): Tim B. Hopper (4): Don C. Hopper (5): Mary D. Hopper (6): Jeff D. Hopper (7): Nancy G. Hopper (8): Barbara H. Hopper (9): Lon H. Hopper (10): Dave H. Hopper (11): Andy J. Hopper (12): Will K. Hopper (13): Art L. Hopper (14): Jack M. Hopper (15): Karen M. Hopper (16): Tracy M. Hopper (17): Wanfang M. Hopper (18): Jeff N. Hopper (19): Nancy O. Hopper (20): Mike R. Hopper (21): Rick T. Hopper (22): Dave W. Hopper (23): Jim W. Hopper (24): Robert Z. Hopper %DEBUG-I-VERIFYIC, exiting command procedure EXAM DBG> |
DECLARE コマンドで指定されたそれぞれの p-name:p-kind の組み合わせは,1 つのパラメータを結び付けます。たとえば1つのコマンド・プロシージャに 5 つのパラメータを引き渡す場合,5 つの対応する p-name:p-kind の組み合わせが必要になります。これらの組み合わせは常に指定した順番に処理されます。
たとえば,次のコマンド・プロシージャ EXAM_GO.COM は,アドレス式(L)とコマンド文字列(M)の 2 つのパラメータを受け取ります。その後,アドレス式が調べられ,コマンドが実行されます。
! ***** デバッガ・コマンド・プロシージャEXAM_GO.COM ***** DECLARE L:ADDRESS, M:COMMAND EXAMINE L; M |
次の例は,検査対象の変数 X,実行対象のコマンド @DUMP.COM を渡す EXAM_GO.COM の実行方法を示しています。
DBG> @EXAM_GO X, "@DUMP" |
組み込みシンボル %PARCNT は,コマンド・プロシージャ内だけで使用できるものであり,コマンド・プロシージャへさまざまな個数のパラメータを引き渡せるようにします。%PARCNT の値は,コマンド・プロシージャへ引き渡す実パラメータの個数を示します。
次の例では,組み込みシンボル %PARCNT が使用されています。コマンド・プロシージャ VAR.DBG には,次の行が含まれています。
! ***** デバッガ・コマンド・プロシージャVAR.DBG ***** SET OUTPUT VERIFY ! 引き渡されるパラメータの個数を表示する。 EVALUATE %PARCNT ! 引き渡されたパラメータをすべて結合して値を取得するまでループする。 FOR I = 1 TO %PARCNT DO(DECLARE X:VALUE; EVALUATE X) |
次のコマンド行は,VAR.DBG にパラメータ 12,37,45 を引き渡して実行します。
DBG> @VAR.DBG 12,37,45 %DEBUG-I-VERIFYIC, entering command procedure VAR.DBG ! 引き渡されるパラメータの個数を表示する。 EVALUATE %PARCNT 3 ! 引き渡されたパラメータをすべて結合して, ! 値を取得するまでループする。 FOR I = 1 TO %PARCNT DO(DECLARE X:VALUE; EVALUATE X) 12 37 45 %DEBUG-I-VERIFYIC, exiting command procedure VAR.DBG DBG> |
VAR.DBG が実行されるとき,%PARCNT の値は 3 です。したがって,VAR.DBG 内の FOR ループは 3 回繰り返されます。FOR ループでは,DECLARE コマンドが 3 つの各実パラメータ(12 が最初)を新しい宣言 X に結び付けます。それぞれの実パラメータは,現在使用中の言語の値式として解釈され,EVALUATE X コマンドがその値を表示します。
13.2 デバッガ初期化ファイルの使用
デバッガ初期化ファイルはコマンド・プロシージャであり,論理名 DBG$INIT が付けられています。このファイルはデバッガの起動時に自動的に実行されます。デバッガを起動するたびにファイル内に記述されたコマンドが自動的に実行されます。
初期化ファイルには,デバッグ環境を整えるため,またはユーザ・プログラムが毎回の実行時にあらかじめ決められた方法で実行されるよう制御するために,デバッグ・セッションを開始するときに必ず入力しなければならないコマンド行が含まれています。
たとえば,ファイル DEBUG_START4.COM に次のコマンドが含まれているとします。
! ***** デバッガ初期化ファイルDEBUG_START4.COM ***** ! デバッグ・セッションを省略時のログ・ファイル(SYS$DISK:[]DEBUG.LOG)に記 録する。 SET OUTPUT LOG ! ! コマンド・プロシージャから読み込まれたコマンドをエコーバックする。 SET OUTPUT VERIFY ! ! ソース・ファイルが現在の省略時ディレクトリにない場合は[SMITH.SHARE]を 使用する。 SET SOURCE [],[SMITH.SHARE] ! ! 画面モードを起動する。 SET MODE SCREEN ! ! シンボルSBをSET BREAKコマンドとして定義する。 DEFINE/COMMAND SB = "SET BREAK" ! ! SHOW MODULE *コマンドをKP7に割り当てる。 DEFINE/KEY/TERMINATE KP7 "SHOW MODULE *" |
このファイルをデバッガ初期化ファイルにするには,DCLのDEFINE コマンドを使用します。次に例を示します。
$ DEFINE DBG$INIT WORK:[JONES.DBGCOMFILES]DEBUG_START4.COM |
デバッガ・ログ・ファイルは,デバッグ・セッションの履歴を記録します。デバッグ・セッションの間に,入力された各コマンドとその結果のデバッガの出力がファイルに保存されます。次にデバッガ・ログ・ファイルの例を示します。
SHOW OUTPUT !noverify, terminal, noscreen_log, logging to DSK2:[JONES.P7]DEBUG.LOG;1 SET STEP NOSOURCE SET TRACE %LINE 30 SET BREAK %LINE 60 SHOW TRACE !tracepoint at PROG4\%LINE 30 GO !trace at PROG4\%LINE 30 !break at PROG4\%LINE 60 . . . |
DBG> プロンプトは記録されず,デバッガの出力内容は感嘆符が付けられてコメントになるので,ファイルは修正なしでデバッガ・コマンド・プロシージャとして使用することができます。したがって,長いデバッグ・セッションに割り込みがかかったとき,ログ・ファイルを他のデバッガ・コマンド・プロシージャと同じように実行することができます。ログ・ファイルを実行すると,前回中断したところまでデバッグ・セッションが復元されます。
デバッガ・ログ・ファイルを作成するには,SET OUTPUT LOG コマンドを使用します。省略時には,デバッガはログを SYS$DISK:[]DEBUG.LOG に書き込みます。デバッガ・ログ・ファイルに名前を付けるには,SET LOG コマンドを使用します。省略時のファイル指定のどのフィールドでも上書きすることができます。たとえば,次のコマンドを入力すると,その後デバッガはセッションをファイル [JONES.WORK2]MONITOR.LOG に記録します。
DBG> SET LOG [JONES.WORK2]MONITOR DBG> SET OUTPUT LOG |
SET OUTPUT LOG コマンドをデバッガ初期化ファイルに入力する場合もあります。第 13.2 節 を参照してください。
SHOW LOG コマンドは,デバッガがログ・ファイルに書き込みを行っているかどうかを報告し,現在のログ・ファイルを示します。SHOW OUTPUT コマンドは,現在の出力オプションをすべて示します。
画面モードでデバッグしているとき,SET OUTPUT SCREEN_LOG コマンドを使用して画面の内容を更新される様子そのままに記録することができます。このコマンドを使用するには,デバッグ・セッションのログがすでに記録中になっていなければなりません。すなわち,SET OUTPUT SCREEN_LOGコマンドは,SET OUTPUT LOG コマンドを入力したあとでだけ有効になります。SET OUTPUT SCREEN_LOG コマンドで画面情報を保存すると大きなログ・ファイルが作成されるため,長いデバッグ・セッションで使用することは望ましくありません。画面モードの情報を保存するその他の方法については,SAVE コマンドおよび EXTRACT コマンドの説明を参照してください。
ログ・ファイルをコマンド・プロシージャとして使用するときは,まず SET OUT PUT VERIFY コマンドを入力して,読み込まれたデバッガ・コマンドをエコーバックするようにしなければなりません。
前へ | 次へ | 目次 | 索引 |