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の関係にはない。
論理的な思考ができない人にこのような傾向がある。
本が床に落ちた原因は人手によるかもしれないし地震かも知れない。
物事が起きる原因はいくつもあるのに原因はただ一つと考えているのは
全くの誤りであるし論理的な思考とは言えない。
デバッグほど論理的思考が試される場面はない。
慌てて原因を特定したがるのではなく論理的にジックリと思考して欲しい。
