Hi All,
I am looking for a sample program which can give entire call stack based on the given job details.
I am looking for a sample program which can give entire call stack based on the given job details.
DSPJOB JOB(Z/Y/X) OUTPUT(*PRINT) OPTION(*PGMSTK)
DSPJOB JOB(Z/Y/X) OUTPUT(*) OPTION(*PGMSTK)
D* ----- Call Stack API ---------------------------------
d FindCaller PR Extpgm('QWVRCSTK')
d 2000a
d 10I 0
d 8a CONST
d 56a
d 8a CONST
d 15a
D* ----- Call Stack Data --------------------------------
d Var DS 2000
d BytAvl 10I 0
d BytRtn 10I 0
d Entries 10I 0
d Offset 10I 0
d EntryCount 10I 0
D* ----- Call Stack Job Information ---------------------
d JobIdInf DS
d JIDQName 26a Inz('*')
d JIDIntID 16a
d JIDRes3 2a Inz(*loval)
d JIDThreadInd 10I 0 Inz(1)
d JIDThread 8a Inz(*loval)
D* ----- Call Stack Program Names -----------------------
d Entry DS 256
d EntryLen 10I 0
d ReqstLvl 10I 0 Overlay(Entry:21)
d PgmNam 10a Overlay(Entry:25)
d PgmLib 10a Overlay(Entry:35)
d VarLen s 10I 0 Inz(%size(Var))
d ApiErr s 15a
d Caller s 50a
d WhoCalled s 10a
d i s 10I 0
// ==============================================================
// ----- Find the previous program name from the call stack -----
BegSR GetCallStackInfo;
CallP FindCaller(Var : VarLen : 'CSTK0100' : JobIdInf
: 'JIDF0100' : ApiErr );
For i = 1 to EntryCount;
Entry = %subst(Var:Offset + 1);
Caller = %trim(PgmLib) + '/' + %trim(PgmNam);
// Ignore c#Pgm1 = FMIFTLOG4
// Ignore c#Pgm2 = FMIFTLOG41
// Ignore c#Pgm3 = FMIFTLOG42
// Ignore IBM programs (Start with Q*)
// Ignore PROC_NAME (should be same as c#Pgm2)
If ( PgmNam <> PROC_NAME And
WhoCalled = *blanks And
PgmNam <> c#Pgm_1 And
PgmNam <> c#Pgm_2 And
PgmNam <> c#Pgm_3 And
%SubSt(PgmNam : 1 : 1) <> 'Q'
);
WhoCalled = PgmNam;
Endif;
Offset = Offset + EntryLen;
Endfor;
FLCHNL = %trim(p@FrmCmd);
FLRQDT = %dec(%char(%date():*iso0):8:0);
FLRQTM = %dec(%char(%time():*hms0):6:0);
EndSR;
// ==============================================================
D* ----- Call Stack API --------------------------------- d FindCaller PR Extpgm('QWVRCSTK') d LikeDS(Var) d 10I 0 Const d 8a Const d LikeDS(jobidinf) Const d 8a Const d Like(apierr) D* ----- Call Stack Data -------------------------------- d Var DS 2000 d BytAvl 10I 0 d BytRtn 10I 0 d Entries 10I 0 d Offset 10I 0 d EntryCount 10I 0 D* ----- Call Stack Job Information --------------------- d JobIdInf DS d JIDQName 26a d JIDJName 10a Overlay(jidqname) d JIDJUser 10a Overlay(jidqname : 11) d JIDJNumber 6a Overlay(jidqname : 21) d JIDIntID 16a d JIDRes3 2a Inz(*loval) d JIDThreadInd 10I 0 Inz(2) d JIDThread 8a Inz(*loval) D* ----- API error structure ---------------------------- [FONT=courier new]D APIErr DS Qualified D BytesPr 10i 0 D BytesAv 10i 0 D MsgID 7a D Reserv 1a D MsgDta 256a [/FONT] D* ----- Call Stack Program Names ----------------------- d ptrEntry * d Entry DS 256 Based(ptrentry) d EntryLen 10I 0 d ReqstLvl 10I 0 Overlay(Entry:21) d PgmNam 10a Overlay(Entry:25) d PgmLib 10a Overlay(Entry:35) d Caller s 50a d WhoCalled s 10a d Cntr s 10I 0 // ============================================================== // ----- Find the previous program name from the call stack ----- BegSR GetCallStackInfo; [FONT=courier new] apierr.bytespr = %Size(apierr); jidjname = 'job name'; jidjuser = 'job user'; jidjnumber = 'job number';[/FONT] FindCaller(Var : %Size(var) : 'CSTK0100' : JobIdInf : 'JIDF0100' : ApiErr ); [FONT=courier new] IF apierr.bytesav = 0; FOR cntr = 1 to entrycount;[/FONT] ptrentry = %Addr(var) + offset + (entrylen * (cntr - 1)); caller = %Trim(pgmlib) + '/' + pgmnam; IF PgmNam <> PROC_NAME And WhoCalled = *blanks And PgmNam <> c#Pgm_1 And PgmNam <> c#Pgm_2 And PgmNam <> c#Pgm_3 And %SubSt(PgmNam : 1 : 1) <> 'Q'; WhoCalled = PgmNam; ENDIF; ENDFOR; [FONT=courier new] ENDIF;[/FONT] ENDSR; // ==============================================================
[FONT=courier new]d ApiErr s 15a ... FindCaller(Var : %Size(var) : 'CSTK0100' : JobIdInf : 'JIDF0100' : ApiErr );[/FONT]
Comment