デバッグのためにコンソールにMSGを出さない
少しアセンブラーに慣れてくると作ったプログラムのデバッグが気になってくる。思うような結果が出ない、ABENDしてしまう、など上手く動かないことはわかるが、どうしてそうなるかがわからない。この部分は通ったか、あそこはどうか、と書いたプログラムがどう流れているのかが知りたくなる。そんな時コンソールにメッセージを出すWTOと言うOSマクロの存在なんぞを知ってしまうと、プログラム内の至る所にそれを入れて、どこをどう通ったかコンソールにメッセージを出してプログラムの流れを掴もうとしたくなる。
だがこの方法はできればやらない方がいい。正直言ってみっともないし(腕前のなさを宣伝してるようなもの)、他人のデバッグMSGほどうっとおしいものはない。それにもし誤ってループした場合、そのループの中にWTOマクロが入っていると悲惨である。コンソールに大量のMSGが出され、かつシステムのコンソールバッファも滞留する。それが捌けるまでシステムは足を引っ張られ他のジョブも止まってしまう場合がある。MVSはとにかくMSGをさばくことに必死となる。もしそのプログラムのJCLをTSOからサブミットしたならば大騒ぎにならないうちに自分で始末しようとしてもキャンセルすることすらむずかしいであろう。そんな状況になると優先度が比較的低く設定されるTSOユーザー空間などはちっともディスパッチされない。とにかくコンソールからコマンドでジョブをキャンセルしてもらわねばならない。コンソールが一杯でディスプレイコマンドも使えないからオペレーターにもうっとおしがられるし、ビビッて放っておいて大騒ぎになったりすると厳格な運用をしているセンターでは始末書を書かされるかも知れない。協力会社のエンジニアならあなたが怒られるだけでなく、責任者も呼び出されるかも知れない。いずれにしても嫌な思いをすることになる。私はさすがに始末書を書かされたことはないが、駆け出しの頃は何度もやってしまいバツの悪い思いをしたことが何度もある。
プログラムの流れを追うのに要所要所でメッセージを出す方法自体は悪いことではない。基本的なデバッグの方法でもある。問題は出力先なのである。コンソールに出すから問題にもなるし、かっこ悪い。WTOは1行マクロ命令を書くだけで済みお手軽だから使いたくなるのだが、どうせMSGを出すならSYSOUTの方がいい。WTOに比べればDCBを用意してOPENとCLOSEが必要になるが大した手間ではないし、MSGを出すのにはWTOの代わりにPUTマクロを使えばいい。MSGテキストはリテラルで書けばWTO同様に1メッセージ1行で済む。簡単なサンプルを紹介するので参考にして見て欲しい。
MAINENTR CSECT , DEFINE CODE SECTION USING *,12 DEFINE BASE REGISTER STM 14,12,12(13) SAVE CALLER REGISTERS LA 12,0(,15) GR12 -> OUR 1ST BASE ADDRESS LR 15,13 SAVE CALLER SAVEAREA CNOP 0,4 INSURE FULL WORD BOUNDARY BAS 13,*+4+72 AROUND OUR SAVEAREA DC 18F'-1' OUR GPR SAVEAREA ST 15,4(,13) SAVE CALLER SAVEAREA POINTER ST 13,8(,15) SET BACK CHAIN FOR LINK TRACE SPACE , OPEN (DEBUGLOG,OUTPUT) OPEN DEBUGLOG DATASET PUT DEBUGLOG,=C'PASSED LABEL A' < -- WTOの代わりに書くPUTマクロ CLOSE DEBUGLOG CLOSE DEBUGLOG DATASET SPACE , L 13,4(,13) LOAD CALLER SAVEAREA LM 14,12,12(13) RESTORE CALLER GPRS SLR 15,15 SET CC=0 BR 14 RETURN TO CALLER SPACE , DEBUGLOG DCB DDNAME=DEBUGLOG, + DSORG=PS,MACRF=PM,RECFM=FB,LRECL=126 END
プログラムの実行JCLには以下のDD文を追加する。OUTLIMパラメーターは必ず付ける。この例では1000メッセージ出したらジョブの実行を打ち切る。これが無いとPUTを出しながらループしたら場合によってはJES2スプールを一杯にしてしまう。これも起こしてしまうと大騒ぎになる。それでもスプールが一杯になるにはある程度時間が掛かるし、ログオン済みTSO端末の応答がなくなることはないので自分でそのジョブをキャンセルしてからパージできる。
//DEBUGLOG DD SYSOUT=*,OUTLIM=1000
VOS3の場合は2秒間に38回連続して同一テキストのMSGが出るとWTOを出しながらループしていると判定されABENDさせられる。(確かS722だったと記憶している、また監視時間はPARMLIBの設定で変更できる)MVSやMSPには同様のガードはない。JCLのTIMEパラメーターで一定時間CPUを使ったらABENDさせてしまう方法もあるが、数秒であっても相当な数のメッセージが滞留してしまうからコンソールへMSGを出してデバッグするやり方はやはり勧められない。MVSにおけるコンソールは本来センターオペレーターにシステムの異常な状態を通知したり、業務アプリケーションでオペレーターに判断を求めたり、と言ったシステムやプログラムがオペレーターと通信するためのもの。プログラマーがデバッグに使うのは必要最小限にとどめたい。代替の出力先が使えるならそちらを利用すべき。