RPGプログラムでアベンドと呼ばれるエラー・メッセージを
生じるエラーが発生したときの調査と原因の特定と回復の方法を
紹介する。
例えば実行中に次のようなエラーが発生して実行が中断したとする。
(C G D F) 配列指標が範囲外になっている。
応答を入力して,実行キーを押してください。
応答 . . .
F3= 終了 F12= 取消し
このメッセージにすぐに応答してはいけない。
まずはこのエラーが出ている状態で現在の状況を調査することから始める。
(1)呼び出しスタックの表示
システム要求(SYS-REQ)を実行する。
システム要求 システム : Sxxxxxxx 次の 1 つを選択してください。 1. 2 次ジョブのサインオンの表示 2. 前の要求の終了 3. 現行ジョブの表示 4. メッセージ表示 5. メッセージの送信 6. システム操作員メッセージの表示 7. ワークステーション・ユーザーの表示 80. ジョブの切り離し 90. サインオフ
オプション3.を選択してさらに呼出しスタックを調べる。
ジョブの表示 システム : Sxxxxxx ジョブ : QPADEV0004 ユーザー : QTR 番号 : 856962 次の 1 つを選択してください。 1. ジョブ状況属性の表示 2. ジョブ定義属性表示 3. ジョブ実行属性の表示(活動状態の場合) 4. スプール・ファイルの表示 10. ジョブ・ログ表示(活動状態,ジョブ待ち行列上,または保留中の場合) 11. 呼び出しスタックの表示(活動状態の場合) 12. ロックの表示(活動状態の場合) 13. ライブラリー・リストの表示(活動状態の場合) 14. オープンされたファイルの表示(活動状態の場合) 15. ファイル一時変更の表示(活動状態の場合) 16. コミットメント制御状況の表示(活動状態の場合) 続く ... 選択項目 F3= 終了 F12= 取り消し
(2) 「11. 呼び出しスタックの表示」を選択する。
呼び出しスタックの表示 システム : Sxxxxxx ジョブ : QPADEV0001 ユーザー : QTR 番号 : 856959 スレッド: 00000007 タイプ プログラム ステートメント プロシージャー QCMD QSYS /0517 QUICMENU QSYS /00C1 1 QUIMNDRV QSYS /060F 2 QUIMGFLW QSYS /04D7 3 QUICMD QSYS /056E 4 QCMD QSYS /01C8 DBG001 TEST.COM _QRNP_PEP_DBG001 DBG001 TEST.COM 19 DBG001 QRNXIE QSYS 11 _QRNX_G_FC_H QRNXIE QSYS 2 _QRNX_DFT_ERROR QRNXIE QSYS 17 _QRNX_INQ QRNXIE QSYS 16 IトヌMヘキ QMHSNDPM QSYS /0ADF 続く ... F3= 終了 F5= 最新表示 F11= 活動化グループの表示 F12= 取り消し F16=ジョブ・メニュー F17= 先頭 F18= 最後 F22= フィールド全体の表示
(3) コンパイル・リストを確認する。
エラーの箇所のステートメントは(2)で 19 とわかっているのでそのステートメントの実行は
行 <---------------------- ソースの仕様 ------------------------------------>
番号 ....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8
ソ ー ス ・ リ ス ト
1 H DFTNAME(DBG001) DATEDIT(*YMD/) BNDDIR('QC2LE')
2 F********** 配列指標をオーバーするエラー ******************************
3 F*
4 F**********************************************************************
5
6 * CRTRPGMOD OBJ(QTEMP/DBG001) SRCFILE(R610SRC/QRPGLESRC)
7 * DBGVIEW(*SOURCE) AUT(*ALL)
8 * CRTPGM PGM(ASNET.COM/DBG001) MODULE(QTEMP/DBG001) ACTGRP(*NEW)
9 * AUT(*ALL)
10
11 *-------------------------------------------------------------------*
12 * 2020/09/07 : 作成
13 *-------------------------------------------------------------------*
14 *( 作業変数
15 D AR S 1A DIM(10)
16 D N S 4S 0
17
18 C 1 DO 12 N
19 C MOVE '*' AR(N)
20 C ENDDO
21 C SETON LR----
22 C RETURN
* * * * * * ソ ー ス の 終 わ り * * * * * *
によって
19 C MOVE '*' AR(N)
であることがわかる。
従ってフィールド値 :N の値を調べればよいことがわかる。
(4) エラーに対して D (=Dump)で応答する。
(5) ダンプ・リストを調べる。
WRKOUTQ QEZDEBUG で最後に出力されているスプールが(4)で出力されたプログラムの
ダンプ・リストであるのでこの中でフィールドの値を調べる。
スプール・ファイルの表示 ファイル . . . : QPPGMDMP 制御 . . . . . . 検索 . . . . . . *...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+. ILE RPG 定様式ダンプ プログラム状況域 : プロシージャー名 . . . . . . . . . . : DBG001 プログラム名 . . . . . . . . . . . . : DBG001 ライブラリー . . . . . . . . . . . : TEST.COM モジュール名 . . . . . . . . . . . . : DBG001 プログラム状況 . . . . . . . . . . . : 00121 (C G D F) 配列指標が範囲外になっている。 直前の状況 . . . . . . . . . . . . . : 00000 エラーのステートメント . . . . . . . : 00000019 RPG ルーチン . . . . . . . . . . . . : *DETC パラメーターの数 . . . . . . . . . . : メッセージ・タイプ . . . . . . . . . : MCH 追加のメッセージ情報 . . . . . . . . : 0603 メッセージ・データ . . . . . . . . . : 添え字値または文字列の範囲エラー。 : : NAME ATTRIBUTES VALUE AR CHAR(1) DIM(10) (1-10) '*' '5C'X N ZONED(4,0) 0011. 'F0F0F1F1'X * * * * * RPG ダンプの終わり * * * * *
N の値は 11 であり配列ARの配列の数 10 をオーバーしたことがわかる。
(6) フィールドの異常値の原因を調べて解決する
ダンプ・リストでフィールドに異常値が見つかったら
・異常値になる原因がある。 ・異常値ではないがプログラムがその値に考慮されていなかった。
などの原因が考えられる。
プログラムを異常値が発生しないように修正するかまたは
その値にも対応するようにプログラムを修正して再コンパイルする。
(7) 修正後に実行してエラーが発生しないことを確認する。
エラーの原因は修正して正しく実行することができることを確かめる。
エラーの原因であると確定できるのは修復して正しく実行できることを
確認して初めてそれがエラーの原因であったと断定することができる。
正しく回復できるまではエラーの原因であるとは言えない。
ここで行ったのは
・エラー行を特定する ・エラー行でのフィールドの値を調べる ・プログラムのロジックを再検討する
という方法であった。エラーの場所と内容を調査することから始めないと
原因を特定することはできない。
—誤った考え方
エラーが発生したときに「○○ のエラーが発生するのは○○が原因である」とか
「○○ のエラーが発生するのは何が原因ですか?」のように
調べもせずにエラーの原因をひとつだけだけであると類推する考えは全くの誤りである。
エラーの原因は必ずしもひとつではないしエラーと原因は 1対1の関係にはない。
論理的な思考ができない人にこのような傾向がある。
本が床に落ちた原因は人手によるかもしれないし地震かも知れない。
物事が起きる原因はいくつもあるのに原因はただ一つと考えているのは
全くの誤りであるし論理的な思考とは言えない。
デバッグほど論理的思考が試される場面はない。
慌てて原因を特定したがるのではなく論理的にジックリと思考して欲しい。