WRKACTJOB で 「11. 呼び出しスタックの表示」 によってコール・スタックを表示することが
できるが、ユーザー・プログラムを使って自分で直接、スタックの内容を検索したい場合がある。
上位のプログラムの名前を知りたい場合もあるからである。
スタックの内容を検索したいという要求は多くあるのだが、手軽に検索できる方法はこれまで
紹介されてこなかった。
最も簡単な方法としては
DSPJOB JOB(*) OUTPUT(*PRINT) OPTION(*PGMSTK)
としてスタックの内容をスプールに出力し、自分でそのスプールの内容を検索する方法がある。
しかし OS400 のスプール出力は OS400リリースによって予告なしに変更されることが多いので将来をサポートする方法としては適切ではない。
特に V5R3M0 では癖がある。
そこで、ここでは V5R1M0 から使用可能なスタック検索 API : QWVRCSTK を使って行う
スタックの検索方法を紹介する。
PGM
/*---------------------------------------------------------*/
/* RTVCALSTK : コール・スタックの検索 */
/*---------------------------------------------------------*/
DCL VAR(&MSG) TYPE(*CHAR) LEN(80)
DCL VAR(&RCVVAR) TYPE(*CHAR) LEN(1024)
DCL VAR(&RCVLEN) TYPE(*CHAR) LEN(4)
DCL VAR(&JIDF0100) TYPE(*CHAR) LEN(60)
DCL VAR(&JOB) TYPE(*CHAR) LEN(10) +
VALUE('* ')
DCL VAR(&USER) TYPE(*CHAR) LEN(10)
DCL VAR(&JOBNBR) TYPE(*CHAR) LEN(6)
DCL VAR(&JOBID) TYPE(*CHAR) LEN(16)
DCL VAR(&THIND) TYPE(*CHAR) LEN(4)
DCL VAR(&THREAD) TYPE(*CHAR) LEN(8) +
VALUE(X'0000000000000000')
DCL VAR(&APIERR) TYPE(*CHAR) LEN(4) +
VALUE(X'00000000') /* 2 進数 */
DCL VAR(&RESERVE) TYPE(*CHAR) LEN(2) VALUE(X'0000')
DCL VAR(&NUM_BIN) TYPE(*CHAR) LEN(4)
DCL VAR(&NUM) TYPE(*DEC) LEN(8 0)
DCL VAR(&N) TYPE(*DEC) LEN(8 0) VALUE(1)
DCL VAR(&OFFSET_BIN) TYPE(*CHAR) LEN(4)
DCL VAR(&OFFSET) TYPE(*DEC) LEN(8 0)
DCL VAR(&SIZE_BIN) TYPE(*CHAR) LEN(4)
DCL VAR(&SIZE) TYPE(*DEC) LEN(8 0)
DCL VAR(&STACK) TYPE(*CHAR) LEN(512)
DCL VAR(&PGM) TYPE(*CHAR) LEN(10)
DCL VAR(&PGMLIB) TYPE(*CHAR) LEN(10)
MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
CHGVAR VAR(%BIN(&RCVLEN)) VALUE(1024)
CHGVAR VAR(%BIN(&THIND)) VALUE(2)
CHGVAR VAR(&JIDF0100) VALUE(&JOB *CAT &USER *CAT +
&JOBNBR *CAT &JOBID *CAT &RESERVE *CAT +
&THIND *CAT &THREAD)
CALL PGM(QWVRCSTK) PARM(&RCVVAR &RCVLEN +
'CSTK0100' &JIDF0100 'JIDF0100' &APIERR)
CHGVAR VAR(&NUM_BIN) VALUE(%SST(&RCVVAR 9 4))
CHGVAR VAR(&NUM) VALUE(%BIN(&NUM_BIN))
CHGVAR VAR(&OFFSET_BIN) VALUE(%SST(&RCVVAR 13 4))
CHGVAR VAR(&OFFSET) VALUE(%BIN(&OFFSET_BIN))
CHGVAR VAR(&OFFSET) VALUE(&OFFSET + 1)
LOOP:
CHGVAR VAR(&SIZE_BIN) VALUE(%SST(&RCVVAR &OFFSET 4))
CHGVAR VAR(&SIZE) VALUE(%BIN(&SIZE_BIN))
CHGVAR VAR(&STACK) VALUE(%SST(&RCVVAR &OFFSET +
&SIZE))
CHGVAR VAR(&PGM) VALUE(%SST(&STACK 25 10))
CHGVAR VAR(&PGMLIB) VALUE(%SST(&STACK 35 10))
SNDPGMMSG MSG('PGM = ' *CAT &PGM) MSGTYPE(*COMP)
SNDPGMMSG MSG('PGMLIB = ' *CAT &PGMLIB) MSGTYPE(*COMP)
IF COND(&N *LT &NUM) THEN(DO)
CHGVAR VAR(&N) VALUE(&N + 1)
CHGVAR VAR(&OFFSET) VALUE(&OFFSET + &SIZE)
GOTO LOOP
ENDDO
RETURN
ERROR: RCVMSG RMV(*NO) MSG(&MSG)
SNDMSG: SNDPGMMSG MSG(&MSG) MSGTYPE(*DIAG)
ENDPGM
この例では QWVRCSTK を使って現行のジョブのスタックの内容を検索してプログラムと
ライブラリーの名前を LOOP してメッセージにログ・アウトしている。