Rational Developer for System z バージョン 7.6

フルスクリーン・モードでのアセンブラー・プログラムのデバッグ

アセンブラーに関する基本的なデバッグ・タスクの説明では、下記 のアセンブラー・プログラムを参照します。

例: デバッグを行うためのアセンブラー・プログラムの例

ここで述べた内容に関して詳しくは、以下のトピックを参照してください。

例: デバッグを行うためのアセンブラー・プログラムの例

下記のプログラムは、デバッグ・タスクを示すために各種のトピックで取り上げられます。

このサンプル・プログラムを実行するには、以下のステップを行います。

  1. このアセンブラー・プログラムのデバッグ・ファイルが、yourid.EQALANGX データ・セット の SUBXMP および DISPARM メンバーにあることを確認します。
  2. Debug Tool を始動します。
  3. デバッグ・ファイルの情報をロードするには、次のコマンドを入力します。
    LDD (SUBXMP,DISPARM)

このプログラムは、アセンブラー・サブルーチン (DISPARM) を呼び出す アセンブラー・メインルーチン (SUBXMP) の簡単な例です。

ロード・モジュール: XMPLOAD

SUBXMP.ASM

**************************************************************
*                                                            *
*  NAME: SUBXMP                                              *
*                                                            *
*        A simple main assembler routine that brings up      *
*        Language Environment, calls a subroutine, and       *
*        returns with a return code of 0.                    *
*                                                            *
**************************************************************
SUBXMP   CEEENTRY PPA=XMPPPA,AUTO=WORKSIZE
         USING WORKAREA,R13
* Invoke CEEMOUT to issue the greeting message
         CALL  CEEMOUT,(HELLOMSG,DEST,FBCODE),VL,MF=(E,CALLMOUT)
* No plist to DISPARM, so zero R1. Then call it.
         SLR   R0,R0
         ST    R0,COUNTER
         LA    R0,HELLOMSG
         SR    R01,R01 ssue a message
         CALL  DISPARM                CALL1 
* Invoke CEEMOUT to issue the farewell message
         CALL  CEEMOUT,(BYEMSG,DEST,FBCODE),VL,MF=(E,CALLMOUT)
* Terminate Language Environment and return to the caller
         CEETERM  RC=0

*        CONSTANTS
HELLOMSG DC    Y(HELLOEND-HELLOSTR)
HELLOSTR DC    C'Hello from the sub example.'
HELLOEND EQU   *

BYEMSG   DC    Y(BYEEND-BYESTART)
BYESTART DC    C'Terminating the sub example.'
BYEEND   EQU   *
DEST     DC    F'2'               Destination is the LE message file
COUNTER  DC    F'-1'

XMPPPA   CEEPPA  ,                Constants describing the code block
*        The Workarea and DSA
WORKAREA DSECT
         ORG   *+CEEDSASZ         Leave space for the DSA fixed part
CALLMOUT CALL  ,(,,),VL,MF=L      3-argument parameter list
FBCODE   DS    3F                 Space for a 12-byte feedback code
         DS    0D
WORKSIZE EQU   *-WORKAREA
         PRINT NOGEN
         CEEDSA  ,                Mapping of the dynamic save area
         CEECAA  ,                Mapping of the common anchor area
R0       EQU   0
R01      EQU   1
R13      EQU   13
         END   SUBXMP             Nominate SUBXMP as the entry point

DISPARM.ASM

**************************************************************
*                                                            *
*  NAME:  DISPARM                                            *
*                                                            *
*        Shows an assembler subroutine that displays inbound *
*        parameters and returns.                             *
*                                                            *
**************************************************************
DISPARM  CEEENTRY PPA=PARMPPA,AUTO=WORKSIZE,MAIN=NO
         USING WORKAREA,R13
* Invoke CEE3PRM to retrieve the command parameters for us
         SLR   R0,R0
         ST    R0,COUNTER
         CALL  CEE3PRM,(CHARPARM,FBCODE),VL,MF=(E,CALL3PRM)      CALL2 
* Check the feedback code from CEE3PRM to see if everything worked.
         CLC   FBCODE(8),CEE000
         BE    GOT_PARM
* Invoke CEEMOUT to issue the error message for us
         CALL  CEEMOUT,(BADFBC,DEST,FBCODE),VL,MF=(E,CALLMOUT)
         B     GO_HOME                 Time to go....
GOT_PARM DS    0H
* See if the parm string is blank.
         LA    R1,1
SAVECTR  ST    R1,COUNTER
         CL    R1,=F'5'                    BUMPCTR 
         BH    LOOPEND
         LA    R1,1(,R1)
         B     SAVECTR
LOOPEND  DS    0H
         CLC   CHARPARM(80),=CL80' '   Is the parm empty?
         BNE   DISPLAY_PARM            No. Print it out.
* Invoke CEEMOUT to issue the error message for us
         CALL  CEEMOUT,(NOPARM,DEST,FBCODE),VL,MF=(E,CALLMOUT)
         B     GO_TEST                 Time to go....

DISPLAY_PARM   DS  0H
* Set up the plist to CEEMOUT to display the parm.
         LA    R0,2
         ST    R0,COUNTER
         LA    R02,80        Get the size of the string
         STH   R02,BUFFSIZE  Save it for the len-prefixed string
* Invoke CEEMOUT to display the parm string for us
         CALL  CEEMOUT,(BUFFSIZE,DEST,FBCODE),VL,MF=(E,CALLMOUT)
*        AMODE Testing
GO_TEST  DS  0H
         L     R15,INAMODE24@
         BSM   R14,R15
InAMode24 Equ  *
         LA    R1,DEST
         O     R1,=X'FF000000'
         L     R15,0(,R1)
         LA    R15,2(,R15)
         ST    R15,0(,R1)
         L     R15,INAMODE31@
         BSM   R14,R15
InAMode31 Equ  *
* Return to the caller
GO_HOME  DS    0H
         LA    R0,3
         ST    R0,COUNTER
         CEETERM  RC=0

*        CONSTANTS
DEST     DC    F'2'               Destination is the LE message file
CEE000   DS    3F'0'              Success feedback code
InAMode24@ DC  A(InAMode24)
InAMode31@ DC  A(InAMode31+X'80000000')
BADFBC   DC    Y(BADFBEND-BADFBSTR)
BADFBSTR DC    C'Feedback code from CEE3PRM was nonzero.'
BADFBEND EQU   *
NOPARM   DC    Y(NOPRMEND-NOPRMSTR)
NOPRMSTR DC    C'No user parm was passed to the application.'
NOPRMEND EQU   *
PARMPPA  CEEPPA ,                 Constants describing the code block
* ===================================================================
WORKAREA DSECT
         ORG   *+CEEDSASZ         Leave space for the DSA fixed part
CALL3PRM CALL  ,(,),VL,MF=L       2-argument parameter list
CALLMOUT CALL  ,(,,),VL,MF=L      3-argument parameter list
FBCODE   DS    3F                 Space for a 12-byte feedback code
COUNTER  DS    F
BUFFSIZE DS    H                  Halfword prefix for following string
CHARPARM DS    CL255              80-byte buffer
         DS    0D
WORKSIZE EQU   *-WORKAREA
         PRINT NOGEN
         CEEDSA  ,                Mapping of the dynamic save area
         CEECAA  ,                Mapping of the common anchor area
MYDATA   DSECT   ,
MYF      DS      F
R0       EQU   0
R1       EQU   1
R2       EQU   2
R3       EQU   3
R4       EQU   4
R5       EQU   5
R6       EQU   6
R7       EQU   7
R8       EQU   8
R9       EQU   9
R10      EQU   10
R11      EQU   11
R12      EQU   12
R13      EQU   13
R14      EQU   14
R15      EQU   15
R02      EQU   2
         END

コンパイル単位のアセンブラーとしての定義とデバッグ・データのロード

アセンブラー・プログラムをデバッグするにはその前に、コンパイル単位 (CU) をアセンブラー CU として定義し、CU のデバッグ・データをロードする必要があります。これは、逆アセンブリー CU として現在 Debug Tool に認識されている CU に対してのみ行うことができます。

LOADDEBUGDATA コマンド (LDD と短縮される) を使用して、逆アセンブリー CU をアセンブラー CU として定義し、この CU のデバッグ・データをロードさせます。 LDD コマンドを実行する場合、単一の CU 名を指定するか、 または括弧で囲んだ CU 名のリストを指定することができます。 指定されるそれぞれの名前は、以下のいずれかでなければなりません。

CU 名が現在 Debug Tool に認識されている場合、その CU は即時にアセンブラー CU としてマークされ、以下のようにして、そのデバッグ・データのロードが試みられます。

LDD コマンドに指定した CU 名が現在 Debug Tool に認識されていない場合、 メッセージが出され、その名前の CU が認識される (現れる) まで、LDD コマンドは据え置かれます。 その時点で CU が自動的にアセンブラー CU として作成され、デフォルト・データ・セット名または現行の SET DEFAULT LISTINGS 指定を使用してデバッグ・データのロードが試みられます。

CU に対して LDD コマンドを入力した後は、CU を逆アセンブリー CU として表示できません。

LDD コマンドを入力した後 Debug Tool が関連のアセンブラー・デバッグ・データを見つけられない場合、 その CU は逆アセンブリー CU ではなくアセンブラー CU です。 この CU に対してもう一度 LDD コマンドを入力することはできません。 ただし、SET DEFAULT LISTING コマンドまたは SET SOURCE コマンドを入力して、 関連のデバッグ・データを別のデータ・セットからロードすることができます。

据え置き LDD

前の節で説明したように、LDD コマンドを使用して、CU が Debug Tool に認識される前に、その CU をアセンブラー CU として識別することができます。 これを据え置き LDD と呼びます。 この場合、CU が現れると、即時にアセンブラー CU としてマークされ、 デフォルト・データ・セット名または現在 SET DEFAULT LISTINGS で指定されているデータ・セットから、デバッグ・データのロードが試みられます。

この方法でデバッグ・データを見つけられない場合は、CU が現れた後で SET SOURCE または SET DEFAULT LISTINGS コマンドを使用して、正しいデータ・セットからデバッグ・データ がロードされるようにしなければなりません。 これは、以下のようなコマンドを使用して行うことができます。

AT APPEARANCE mycu SET SOURCE (mycu) hlq.qual1.dsn

あるいは、"mycu" が現れた後、その他の理由で停止するまで待機してから、SET SOURCE または SET DEFAULT LISTING コマンドを使用して、Debug Tool に正しいデータ・セット を指示します。

アセンブラー CU の再出現

有効なアセンブラー・デバッグ・データがロードされた CU が無くなった後、 再表示する場合 (例えば、ロード・モジュールが削除された後で、再ロードされた場合)、 その CU は即時にアセンブラー CU としてマークされ、デバッグ・データは、 前に正常にロードされていたデータ・セットから再ロードされます。

その CU がアセンブラー CU として既に認識されており、 デバッグ・データが既にロードされているので、その CU に対する別の LDD は、 実行する必要がありません (実行できません)。

単一アセンブリー内の複数のコンパイル単位

Debug Tool は、各アセンブラー CSECT を別々のコンパイル単位 (CU) として扱います。 アセンブラー・ソースが複数の CSECT を含む場合、作成する EQALANGX ファイルには すべての CSECT についてのデバッグ情報が含まれます。

ほとんどの場合、アセンブリー内のすべての CSECT はロード・モジュールまたは プログラム・オブジェクトに存在します。ただし 1 つ以上のアセンブリーが 存在しない場合や、同じ名前のほかの CSECT に置換される場合もあります。 そのため、複数の CSECT を含むアセンブリーのデバッグ・データをロードする 方法は 2 つあります。

次のセクションでは、MYPROG と MYPROGA という 2 つの CSECT を生成する アセンブリーの例を使用します。 これら両方の CSECT のデバッグ情報は、データ・セット yourid.EQALANGX(MYPROG) にあります。

単一 LDD コマンドを使用して単一アセンブリー内の複数 CSECT からデバッグ・データをロード

SET LDD ALL が有効である場合、このセクションに記述されているプロセスを実行してください。 すべての CSECT がロード・モジュールやプログラム・オブジェクトに存在する場合、 このプロセスが複数の CSECT を含むアセンブリーのデバッグ・データをロードする 最も簡単な方法です。

コマンド LDD MYPROG を入力すると、Debug Tool は MYPROG と MYPROGA の 両方のデバッグ・データを検索してロードします。 デバッグ・データがロードされると、Debug Tool はデバッグ・データを使用して、 MYPROG と MYPROGA を対象とする 2 つの CU を作成します。

個別の単一 LDD コマンドを使用して単一アセンブリー内の複数 CSECT からデバッグ・データをロード

SET LDD SINGLE が有効である場合、このセクションに記述されているプロセスを実行してください。

コマンド LDD MYPROG を入力すると、Debug Tool は MYPROG と MYPROGA の両方のデバッグ情報を検索してロードします。 ただし、LDD コマンドに MYPROG のみを指定し、SET LDD SINGLE が 有効であるため、Debug Tool は MYPROG のデバッグ情報のみを使用します。 その後、 コマンド LDD MYPROGA を入力すると、Debug Tool は以下のステップを実行します。

  1. LDD MYPROG コマンドを入力する前に SET SOURCE コマンドを入力した場合、Debug Tool は SET SOURCE コマンドで指定されたデータ・セットからデバッグ・データをロードします。
  2. SET SOURCE コマンドを入力しなかった場合、または Debug Tool がステップ 1 でデバッグ情報を 検出しなかった場合、Debug Tool は以前にロードされたデバッグ情報をすべて検索します。Debug Tool が MYPROGA の名前と CSECT 長に一致する名前と CSECT 長を検出した場合、Debug Tool はこのデバッグ情報を使用します。

デバッグ・データをロード後に単一アセンブリー内の複数 CSECT をデバッグ

アセンブリー内の両方の CSECT のデバッグ・データをロードすると、 いずれかのコンパイル単位のデバッグを開始することができます。 両方の CSECT の内容がソース・リストに表示されていても、現在限定対象となっている コンパイル単位内にしかブレークポイントを設定できません。

ソース・リストを見る場合、ある CSECT 内の現在限定対象外の全行にはそのオフセット・フィールドの直前とステートメント番号の直後にアスタリスクが入ります。このアスタリスクの付いたステートメント上に行ブレークポイントまたはステートメント・ブレークポイントを設定したい場合、含んでいるコンパイル単位に対して最初に限定する必要があります。そのためには以下のコマンドを使用します。

SET QUALIFY CU compile_unit_name;

このコマンドの入力後に、これらのアスタリスクはブレークポイント設定対象の行から除去されます。アスタリスクがないことの意味は、その行上に行ブレークポイントまたはステートメント・ブレークポイントを設定可能であることを示します。

コンパイル単位のデバッグ・データをロードするまでは、 SET QUALIFY コマンドを使用してアセンブラー・コンパイル単位に 限定することはできません。

ある特定のアセンブラー・ルーチンが呼び出されたときの停止

このトピックでは、AT ENTRY コマンドを使用して、ルーチンが呼び出された直後に停止する方法を説明します。これらのコマンドの説明には、例: デバッグを行うためのアセンブラー・プログラムの例 が使用されます。

DISPARM ルーチンが呼び出された後で停止するには、次のコマンドを入力します。

AT ENTRY DISPARM

DISPARM ルーチンが呼び出された後に、R1 が 0 である場合にのみ停止するには、以下のコマンドを入力します。

AT ENTRY DISPARM WHEN R1=0;

AT CALL コマンドは、アセンブラー・ルーチンでサポートされません。 アセンブラー・ルーチンが呼び出されたときに Debug Tool を停止するのに AT CALL コマンド を使用しないでください。

アセンブラー・プログラムが停止したステートメントの特定

プログラム内に多くのブレークポイントを設定している場合、以下のコマンドを入力して、プログラムが停止した場所を Debug Tool によって特定することができます。

QUERY LOCATION

Debug Tool ログ・ウィンドウには、次の例と同様なものが表示されます。

QUERY LOCATION
You are executing commands in the ENTRY XMPLOAD ::> DISPARM breakpoint.
The program is currently entering block XMPLOAD ::> DISPARM.

アセンブラー変数またはストレージの値の表示および変更

単一の変数の内容をリストするには、ソース・ウィンドウ内の変数名の出現箇所にカーソルを移動し、PF4 (LIST) を押します。値はログ・ウィンドウに表示されます。これは、コマンド行に LIST variable を入力するのと同等です。

例えば、SUBXMP プログラムを  CALL1  というラベルの付いたステートメントまで 実行するには、Debug Tool コマンド行に AT 70 ; GO ; と入力します。行 67 が表示されるまでスクロールします。 カーソルを COUNTER の上に移動し、PF4 (LIST) を押します。 これにより、ログ・ウィンドウに次のように表示されます。

LIST ( COUNTER )
COUNTER = 0

COUNTER の値を 1 に変更するには、COUNTER = 0 の行に COUNTER = 1 と 上書きし、Enter を押してこれをコマンド行に置き、Enter を再度押してこのコマンドを出します。

レジスター R0 に入ったアドレスの、2 バイト先のストレージ 16 バイトの内容をリストするには、 コマンド行でコマンド LIST STORAGE(R0->+2,16) を入力し、Enter を押します。 指定されたストレージの内容がログ・ウィンドウに表示されます。

LIST STORAGE( R0 -> + 2 , 16 )
000C321E  C8859393 96408699 969440A3 888540A2   *Hello from the s*

このストレージの最初の 2 バイトを X'C182' に変更するには、コマンド行で コマンド R0->+2 <2> = X'C182'; を入力し、Enter を押してコマンドを出します。

次に、PF2 (STEP) を押して DISPARM の呼び出しにステップイントゥし、CALL2 という ラベルの付いたステートメントまで進みます。変数 COUNTER の属性を表示するには、次の Debug Tool コマンドを出します。

DESCRIBE ATTRIBUTES COUNTER

結果はログ・ウィンドウに次のように表示されます。

ATTRIBUTES for COUNTER
   Its address is  1B0E2150 and its length is 4
   DS F

16 進アドレスをシンボリック・アドレスに変換する方法

アセンブラー・プログラムまたは逆アセンブリー・プログラムをデバッグする 場合、16 進アドレスで表されたシンボリック・アドレスを判別したい場合があります。 これは、%WHERE 組み込み関数を指定した LIST コマンドを使用することによって行うことができます。 例えば、以下のコマンドは、X'1BC5C' のシンボリック・ロケーション を示すストリングを戻します。

LIST %WHERE(X'1BC5C')

このコマンドを入力した後、Debug Tool は以下の結果を表示します。

PROG1+X'12C'

この結果は、アドレス X'1BC5C' が、CSECT PROG1 内のオフセット X'12C' に対応していることを示します。

条件が真である場合に限ったアセンブラーの行での停止

ユーザー・プログラムの特定の部分が、最初の数千回は 正常に機能しますが、ある条件のもとでは失敗するということが よくあります。行のブレークポイントの設定では、GO コマンドを繰り返し入力する必要があるため非効率的です。

例: デバッグを行うためのアセンブラー・プログラムの例

DISPARM プログラムで COUNTER 変数が 3 に設定されている場合に Debug Tool を停止するには、 次のコマンドを入力します。

AT 78 DO; IF COUNTER ^= 3 THEN GO; END;

行 78 は、 BUMPCTR  というラベルが付いた行です。 このコマンドにより、Debug Tool は行 78 で停止します。COUNTER の値が 3 でない場合、プログラムは続行します。 このコマンドにより、Debug Tool は COUNTER の値が 3 の場合にのみ、行 78 で停止するようになります。

アセンブラー・ルーチンのトレースバックの実施

プログラミング・エラーの検討中に、どのような順序の呼び出しがそのプログラミング・エラーを もたらしたのかを把握したいことがよくあります。この順序は、トレースバック、 または呼び出し元のトレースバックと呼ばれます。 トレースバック情報を取得するには、次のコマンドを入力します。

LIST CALLS

例: デバッグを行うためのアセンブラー・プログラムの例

例えば、次のコマンドで SUBXMP の例を実行すると、 ログ・ウィンドウに呼び出し元のトレースバックが表示されます。

AT ENTRY DISPARM
GO
LIST CALLS

ログ・ウィンドウには、次のような情報が表示されます。

At ENTRY IN Assembler routine XMPLOAD ::> DISPARM.
From LINE 76.1 IN Assembler routine XMPLOAD ::> SUBXMP.

アセンブラーにおける予期しないストレージ上書きのエラーの検出

プログラムの実行中に、あるストレージが予期せずにその値を変更し、いつ、どこでこのようなことが生じたかを調べたい場合があります。 以下では、値が予期せず変更されたことをプログラムが検出する例を考えます。

L	R0,X'24'(R3)

ロード中のオペランドのアドレスを調べるには、次のコマンドを入力します。

LIST R3->+X'24'

その結果が X'00521D42' であったとします。このアドレスから始まる次の 4 バイトのストレージの値の変更を監視する ブレークポイントを設定するには、次のコマンドを出します。

AT CHANGE %STORAGE(X'00521D42',4)

プログラムの実行中にこのストレージの値が変わると、Debug Tool は停止します。


ご利用条件 | フィードバック

このインフォメーション・センターでは Eclipse テクノロジーが採用されています。(http://www.eclipse.org)