Results 1 to 6 of 6

Thread: program to retrieve call stack

  1. #1
    Driver of cars, eater of food jamief's Avatar
    Join Date
    Jan 2004
    Location
    Belvidere, IL - United States of America
    Age
    49
    Posts
    9,416
    Rep Power
    12605

    Post program to retrieve call stack

    Code:
         **-- Program description:  ----------------------------------------------**---------------------
         **
         **   This program was intended to ease the process of retrieving the
         **   current job's call stack.  The information returned are the program
         **   names and program library names that are displayed by the DSPJOB or
         **   WRKJOB command's call stack panel.  Running the command DSPJOB
         **   OPTION( *PGMSTK ) will show the information referred to above.
         **
         **   
         **
         **
         **-- Parameters:
         **
         **    PxEntNbr    BOTH       The maximum number of call stack entries
         **                           to return in the output array.  A maximum
         **                           of 128 call stack entries can be returned.
         **
         **                           On return this parameter specifies the
         **                           actual number of call stack entries loaded
         **                           in the second parameter.
         **
         **    PxStkEnt    OUTPUT     The retrieved call stack entries are returned
         **                           in this parameter. Both the program name and
         **                           program library is returned for each call
         **                           stack entry as illustrated below:
         **
         **                           1           21          41
         **                           |  entry 1  |  entry 2  |  entry 3  | --
         **
         **                           1     11    21    31    41    51
         **                           | pgm | lib | pgm | lib | pgm | lib | --
         **
         **                           The call stack entries are returned in
         **                           descending call level order.
         **
         **                           This means that the name of the caller of
         **                           this program will be returned in the first
         **                           entry, and the name of the first program
         **                           that was called in this job is found in
         **                           the last entry returned.
         **
         **
         **-- Compilation specification:
         **
         **   CrtBndRpg   Pgm( <library>/callstack )
         **               SrcFile( <library>/QRPGLESRC )
         **
         **
         **-- Header specification:  ---------------------------------------------**
         H Option( *SrcStmt )
         **-- System information:  -----------------------------------------------**
         D PgmSts         SDs
         D  PsPgmNam         *Proc
         **-- Global variables:  -------------------------------------------------**
         D EntNbr          s             10i 0
         D Eix             s             10i 0
         **-- API error data structure:  -----------------------------------------**
         D ApiError        Ds
         D  AeBytPrv                     10i 0 Inz( %Size( ApiError ))
         D  AeBytAvl                     10i 0
         D  AeExcpId                      7a
         D                                1a
         D  AeExcpDta                   128a
         **-- Retrieve call stack API parameters:  -------------------------------**
         D CsRcvVar        Ds
         D  CsBytRtn                     10i 0
         D  CsBytAvl                     10i 0
         D  CsNbrStkE                    10i 0
         D  CsOfsStkE                    10i 0
         D  CsNbrEntRtn                  10i 0
         D  CsThrId                       8a
         D  CsInfSts                      1a
         D  CsCalStk                  32767a
         **
         D CsCalStkE       Ds                  Based( pCalStkE )
         D  CsStkEntLen                  10i 0
         D  CsOfsStmIds                  10i 0
         D  CsNbrStmIds                  10i 0
         D  CsOfsPrcNam                  10i 0
         D  CsLenPrcNam                  10i 0
         D  CsRqsLvl                     10i 0
         D  CsPgmNam                     10a
         D  CsPgmLib                     10a
         D  CsMiInst                     10i 0
         D  CsModNam                     10a
         D  CsModLib                     10a
         D  CsCtlBdy                      1a
         D  CsRsv                         3a
         D  CsActGrpNbr                  10u 0
         D  CsActGrpNam                  10a
         D  CsAddInf                   4096a
         **
         D  CsStmIds                     10a   Dim( 256 )
         D  CsPrcNam                    512a
         **
         D CsJobId         Ds
         D  JiJobNam                     10a   Inz( '*' )
         D  JiUsrNam                     10a
         D  JiJobNbr                      6a
         D  JiIntId                      16a
         D  JiRsv                         2a   Inz( *Allx'00' )
         D  JiThrInd                     10i 0 Inz( 1 )
         D  JiThrId                       8a   Inz( *Allx'00' )
         **
         D RtvCalStk       Pr                  ExtPgm( 'QWVRCSTK' )
         D  RcRcvVar                  32767a
         D  RcRcvVarLen                  10i 0 Const
         D  RcRcvInfFmt                   8a   Const
         D  RcJobId                      56a   Const
         D  RcJobIdFmt                    8a   Const
         D  RcError                   32767a          Options( *VarSize )
         **-- Parameters:  -------------------------------------------------------**
         D PxEntNbr        s              5p 0 inz(10)
         D PxStkEnt        s             20a   Dim( 128 )
         **
         **
         **-- Mainline:  ---------------------------------------------------------**
         **
          /free
                    if  PxEntNbr  > *Zero;
    
                     RtvCalStk( CsRcvVar
                                : %Size( CsRcvVar )
                                : 'CSTK0100'
                                : CsJobId
                                : 'JIDF0100'
                                : ApiError
                                          );
    
                     if  AeBytAvl = *Zero;
                      pCalStkE = %Addr( CsRcvVar ) + CsOfsStkE;
    
                      for EntNbr = 1  to CsNbrEntRtn;
    
                       if CsPgmNam  <> PsPgmNam;
                        Eix +=1;
                        PxStkEnt(Eix) = CsPgmNam + CsPgmLib;
                       endif;
    
                       if  EntNbr = PxEntNbr or
                           EntNbr = CsNbrEntRtn  or
                           EntNbr = %Elem( PxStkEnt );
                        leave;
                       endif;
    
                       pCalStkE += CsStkEntLen;
                      endfor;
    
                     endif;
                    endif;
    
                    PxEntNbr = Eix;
    
                    *InLr =  *On;
                    Return;
          /end-free
         **
    All my answers were extracted from the "Big Dummy's Guide to the As400"
    and I take no responsibility for any of them.

    www.code400.com

  2. # 666
    Circuit advertisement
    Join Date
    Aug 1965
    Location
    Yakutsk, Russia
    Age
    21
    Posts
    1,000,000
     

  3. #2
    Harbinger of Doom tomholden's Avatar
    Join Date
    Dec 2007
    Location
    Lebanon, Tennessee, United States
    Posts
    4,328
    Rep Power
    8644

    Re: program to retrieve call stack

    i'm so proud of you...there's no "B" data types!!!
    I'm not anti-social, I just don't like people -Tommy Holden

  4. #3
    Lord of the Dance
    Join Date
    Aug 2008
    Location
    Memphis - Nashville TN
    Posts
    1,692
    Rep Power
    4709

    Re: program to retrieve call stack

    Quote Originally Posted by tomholden View Post
    i'm so proud of you...there's no "B" data types!!!
    And nice use of pointer based data structures! SWEET!
    Michael Catalani
    Manager of eCommerce Development
    Acceptance Insurance Corporation
    www.AcceptanceInsurance.com
    www.ProvatoSys.com

  5. #4
    Experienced Forum Member
    Join Date
    Mar 2009
    Location
    China
    Posts
    8
    Rep Power
    0

    Re: program to retrieve call stack

    Good job!

    Yet there's another way to retrieve the call stack of the current thread or the initial thread of another job, by MI instruction MATINVS (Materialize Invocation Stack). Here's an example, t101.rpgle.
    Code:
         /**
          * @file t101.rpgle
          *
          * Test of _MATINVS2.
          * Meterialize the call stack of the current thread.
          */
         h dftactgrp(*no)
    
          /copy mih52
         d dsp_proc_name   pr
         d     susptr                      *
         d len             s             10i 0
         d ptr             s               *
         d pos             s               *
         d tmpl            ds                  likeds(matinvs_tmpl_t)
         d                                     based(ptr)
         d inve            ds                  likeds(invocation_entry_t)
         d                                     based(pos)
         d i               s             10i 0
    
          /free
               ptr = %alloc(min_matinvs_tmpl_length);
               tmpl.bytes_in = min_matinvs_tmpl_length;
               matinvs2(tmpl);
    
               len = tmpl.bytes_out;
               ptr = %realloc(ptr : len);
               tmpl.bytes_in = len;
               matinvs2(tmpl);
    
               // check each call stack entry
               pos = ptr + min_matinvs_tmpl_length;
               for i = 1 to tmpl.entries;
                   dsply 'invocation entry: ' '' inve.inv_num;
                   dsp_proc_name(inve.suspend_ptr);
    
                   pos += invocation_entry_length;
               endfor;
    
               dealloc ptr;
               *inlr = *on;
          /end-free
    
         p dsp_proc_name   b
    
         d dsp_proc_name   pi
         d     susptr                      *
    
         d tmpl            ds                  likeds(matptrif_tmpl_t)
         d                                     based(ptr)
         d ptr             s               *
         d ptrd            ds                  likeds(matptrif_susptr_desc_t)
         d                                     based(pos)
         d pos             s               *
         d mask            s              4a
         d proc_name       s             30a
    
          /free
    
               ptr = %alloc(matptrif_susptr_tmpl_length);
               propb( ptr : x'00'
                    : matptrif_susptr_tmpl_length);
               tmpl.bytes_in = matptrif_susptr_tmpl_length;
    
               // init pointer description
               pos = ptr + matptrif_ptrd_offset;
               ptrd.proc_name_length_in = 30;
               ptrd.proc_name_ptr = %addr(proc_name);
    
               // materialize pointer desc
               mask = x'12200000';
                 // bit 3 = 1; program name
                 // bit 6 = 1; module name
                 // bit 10 = 1; procedure name
               matptrif( tmpl : susptr : mask );
    
               // output pgm name, module name, and procedure name
               dsply '    Program name' '' ptrd.pgm_name;
               dsply '    Module name' '' ptrd.mod_name;
    
               if ptrd.proc_name_length_out > ptrd.proc_name_length_in;
                   %subst(proc_name : 29 : 2) = ' <';
               endif;
               dsply '    Prodecure name' '' proc_name;
    
          /end-free
         p dsp_proc_name   e
    Prototype of MATINVS' system built-in _MATINVS2 and related instruction template structures can be found in mih52.rpgleinc.

    HTH!
    Last edited by junleili-cn; August 10th, 2010 at 05:26 PM.
    Regards!
    Junlei Li

  6. #5
    Driver of cars, eater of food jamief's Avatar
    Join Date
    Jan 2004
    Location
    Belvidere, IL - United States of America
    Age
    49
    Posts
    9,416
    Rep Power
    12605

    Re: program to retrieve call stack

    Thanks Tom/Michael.... It came from an original scott K. program I just /free'd it and removed some stuff. so i cant take credit for any of it
    Junlei - Thanks for posting....nice job

    Jamie
    All my answers were extracted from the "Big Dummy's Guide to the As400"
    and I take no responsibility for any of them.

    www.code400.com

  7. #6
    Code400 Newbie
    Join Date
    Nov 2008
    Location
    Hawaii
    Posts
    4
    Rep Power
    0

    Re: program to retrieve call stack

    This seems interesting... how do you get the call stack of another job as the code seems to retrieve only the stack from the current one. Also, is it possible to get all the details like the statement number of the program, activation group, etc...? Thanks.

    Quote Originally Posted by junleili-cn View Post
    Good job!

    Yet there's another way to retrieve the call stack of the current thread or the initial thread of another job, by MI instruction MATINVS (Materialize Invocation Stack). Here's an example, t101.rpgle.
    Code:
         /**
          * @file t101.rpgle
          *
          * Test of _MATINVS2.
          * Meterialize the call stack of the current thread.
          */
         h dftactgrp(*no)
    
          /copy mih52
         d dsp_proc_name   pr
         d     susptr                      *
         d len             s             10i 0
         d ptr             s               *
         d pos             s               *
         d tmpl            ds                  likeds(matinvs_tmpl_t)
         d                                     based(ptr)
         d inve            ds                  likeds(invocation_entry_t)
         d                                     based(pos)
         d i               s             10i 0
    
          /free
               ptr = %alloc(min_matinvs_tmpl_length);
               tmpl.bytes_in = min_matinvs_tmpl_length;
               matinvs2(tmpl);
    
               len = tmpl.bytes_out;
               ptr = %realloc(ptr : len);
               tmpl.bytes_in = len;
               matinvs2(tmpl);
    
               // check each call stack entry
               pos = ptr + min_matinvs_tmpl_length;
               for i = 1 to tmpl.entries;
                   dsply 'invocation entry: ' '' inve.inv_num;
                   dsp_proc_name(inve.suspend_ptr);
    
                   pos += invocation_entry_length;
               endfor;
    
               dealloc ptr;
               *inlr = *on;
          /end-free
    
         p dsp_proc_name   b
    
         d dsp_proc_name   pi
         d     susptr                      *
    
         d tmpl            ds                  likeds(matptrif_tmpl_t)
         d                                     based(ptr)
         d ptr             s               *
         d ptrd            ds                  likeds(matptrif_susptr_desc_t)
         d                                     based(pos)
         d pos             s               *
         d mask            s              4a
         d proc_name       s             30a
    
          /free
    
               ptr = %alloc(matptrif_susptr_tmpl_length);
               propb( ptr : x'00'
                    : matptrif_susptr_tmpl_length);
               tmpl.bytes_in = matptrif_susptr_tmpl_length;
    
               // init pointer description
               pos = ptr + matptrif_ptrd_offset;
               ptrd.proc_name_length_in = 30;
               ptrd.proc_name_ptr = %addr(proc_name);
    
               // materialize pointer desc
               mask = x'12200000';
                 // bit 3 = 1; program name
                 // bit 6 = 1; module name
                 // bit 10 = 1; procedure name
               matptrif( tmpl : susptr : mask );
    
               // output pgm name, module name, and procedure name
               dsply '    Program name' '' ptrd.pgm_name;
               dsply '    Module name' '' ptrd.mod_name;
    
               if ptrd.proc_name_length_out > ptrd.proc_name_length_in;
                   %subst(proc_name : 29 : 2) = ' <';
               endif;
               dsply '    Prodecure name' '' proc_name;
    
          /end-free
         p dsp_proc_name   e
    Prototype of MATINVS' system built-in _MATINVS2 and related instruction template structures can be found in mih52.rpgleinc.

    HTH!

  8. # 666
    Circuit advertisement
    Join Date
    Aug 1965
    Location
    Yakutsk, Russia
    Posts
    1,000,000
     

Facebook Comments


Similar Threads

  1. Finding a Call Stack Entry
    By uj41724 in forum RPG/RPGLE
    Replies: 2
    Last Post: February 24th, 2010, 04:38 AM
  2. Call stack enry not found.
    By jhang1522 in forum RPG/RPGLE
    Replies: 2
    Last Post: March 11th, 2007, 11:22 PM
  3. call stack
    By john in forum ANY THING GOES
    Replies: 1
    Last Post: September 27th, 2006, 09:43 AM
  4. call stack
    By shankar.as400 in forum ANY THING GOES
    Replies: 2
    Last Post: April 28th, 2006, 05:56 AM
  5. Call stack entry problem
    By vinod in forum RPG/RPGLE
    Replies: 3
    Last Post: March 28th, 2006, 08:11 AM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •