From YiPs Wiki (i powered)

XMLService: XMLSERVICE Debug

(click to open)

Quick Page Table of Contents

Scanning…

XMLSERVICE/Toolkit debugging and service

Goto Main Page
Goto Documents

Who is this page for?

Instructions designed for IBM i developer learning PHP and XMLSERVICE …

Debug technique: It’s as easy as 1–2−3–4−5–6−7–8−9 :)

  1. Run the test script that contains control “*debug” and script will “hang” while it waits on #2
    $ctl .= " *debug";
    
  2. A MSGW inquiry message in DSPMSG QSYSOPR will be generated by the toolkit. Note the job information (number, name, user) provided in the MSGW.
  3. STRSRVJOB using that job information as parameters.
  4. STRDBG with the program and library you wish to debug.
  5. Answer the MSGW. Any answer will do—”G” is fine.
  6. The RPG program source will appear in debug mode in your terminal, ready to step through, allowing you to inspect variables, etc.
  7. When done inspecting and stepping, let the RPG program complete (using function keys indicated on screen).
  8. ENDDBG
  9. ENDSRVJOB
Other debug options …
           Job1 (threaded)   Job 2                        Job 3 (DB2 userid/password)    Job 4 (optional XTOOLKIT job)  
                             (ctl=*debugcgi)              (ctl=*debugproc)                (ctl=*debug)
browser -> Apache          ->XMLCGI (Apache CGI child) -> QSQSRVR (XMLSERVICE *here) 
                                                       -> QSQSRVR (XMLSERVICE client) -> XTOOLKIT (XMLSERVICE ipc=/tmp/flinstone)

$ctl .= " *debugcgi";  // Job 2 - debug XMLCGI to see REST/HTTP data passed by client (when using REST only)
$ctl .= " *debugproc"; // Job 3 - debug XMLSERVICE "client" to see DB2 passed data (DB2 interface)
$ctl .= " *debug";     // Job 4 - debug XMLSERVICE "server" to see XMLSERVICE calls (DB2 interface)
                       // Note:   when ctl='*here', both XMLSERVICE "client"/"server" 
                       //         are in QSQSRVSR job (NO XTOOLKIT job)
                       // remote: Attaching with LUW drivers changes QSQSRVR ...
                       //   CLIENT (Client Access drivers) <==> QZDAxxxx
                       //   CLIENT (DB2 Connect drivers)   <==> QRWxxxx

Tips

This is a collection of debug tips and where you may find your problem data.

Working with service provider?

Here are a few common things that can provide useful information if working with outside support people.

When you have no idea (dumping many processes)?

Some times you just have no idea what is going on, here is a handy macro to dump a lot of stacks.

STRSST/STRDST
1. Start a service tool
4. Display/Alter/Dump
1. Display/Alter storage
... or option for dump to printer ...
2. Licensed Internal Code (LIC) data
14. Advanced analysis
 Option    Command                                                             
    1      processinfo

In this case dumping all process dealing with keyword "ZEND" appearing in job ...

                       Specify Advanced Analysis Options                       
 Output device  . . . . . . :   Display
 Type options, press Enter.
   Command . . . . :   PROCESSINFO
   Options . . . . .   -NAMES ZEND                                             

Note:
Information dumped printer/display is same as paseps macro.

Check active XMLSERVICE job …

If you are using private connections (InternalKey or $ipc=‘/tmp/packers’), the XMLSERVICE job is probably available for examination with wrkactjob.

                             Work with Active Jobs                     LP0264D
                                                             05/17/12  11:35:12
 CPU %:      .0     Elapsed time:   00:00:00     Active jobs:   313

 Type options, press Enter.
   2=Change   3=Hold   4=End   5=Work with   6=Release   7=Display message
   8=Work with spooled files   13=Disconnect ...
                     Current
 Opt  Subsystem/Job  User        Type  CPU %  Function        Status
 5      XTOOLKIT     DB2         BCH      .0  PGM-XMLSERVICE   SEMW

1) Use option 5=work -> 10. Display job log -> F10=Display detailed messages to examine joblog on errors …

                              Display All Messages          
                                                             System:   LP0264D
 Job . . :   XTOOLKIT      User . . :   DB2           Number . . . :   435915

  >> CALL PGM(XMLSERVICE/XMLSERVICE) PARM('/tmp/packers')
     Pointer not set for location referenced.
     Application error.  MCH3601 unmonitored by ZZSRV at statement 0000000448,
       instruction X'0000'.

2) Use option 5=work -> 11. Display call stack -> F5=Refresh to examine stack during stress tests …

                               Display Call Stack
                                                             System:   LP0264D
 Job:   XTOOLKIT       User:   DB2            Number:   437582
 Thread:   0000000C


 Type  Program                  Statement         Procedure
    1  QCMD       QSYS                     /01C8
       XMLSERVICE XMLSERVICE                      _QRNP_PEP_XMLSERVICE
       XMLSERVICE XMLSERVICE    1133              XMLSERVICE
       XMLSERVICE XMLSERVICE    4607              RUNSERVER
       XMLSERVICE XMLSERVICE    2983              SIGSETTIMEOUT
       XMLSERVICE XMLSERVICE    2876              SIGTIMEROFF
       QP0SSRV1   QSYS          19                setitimer
       QP0SSRV2   QSYS          159               qp0sitimer__F12qp0sitimer_t >

Check the logs …

Check PHP log for messages …

  •  On my IBM i machine ...
    EDTF STMF('/usr/local/zendsvr/var/log/php.log')
    -- or --
    call qp2term (or ssh myibmi)
    > tail /usr/local/zendsvr/var/log/php.log
    ... stuff
    ... in /MYASP2/www/zend2/htdocs/hello.php on line 1
    
  •  On my Linux machine ...
    $ tail /usr/local/zend/var/log/php.log
    [16-May-2012 16:30:12] PHP Warning:  db2_close() expects parameter 1 to be resource ...
    

Check Apache logs for messages …

  •  error logs for date in question ...
    EDTF STMF('/myasp2/www/zend2/logs/error_log.Q112051500')
    -- or --
    call qp2term (or ssh myibmi)
    > tail /myasp2/www/zend2/logs/error_log.Q112051500
    [Tue May 15 17:10:11 2012] [error] [client 9.5.158.38] CGI PROGRAM /QSYS.LIB/XMLSERVICE.LIB/XMLCGI.PGM RETURNED EXCEPTION ID CEE9901
    [Tue May 15 17:10:11 2012] [error] [client 9.5.158.38] SEE JOBLOG FOR JOB 428979/QTMHHTTP  /ZEND2  
    
  •  access logs for date in question ...
    EDTF STMF('/myasp2/www/zend2/logs/access_log.Q112051500')
    -- or --
    call qp2term (or ssh myibmi)
    > tail /myasp2/www/zend2/logs/access_log.Q112051500
    9.5.158.38 - - [15/May/2012:17:47:41 -0500] "GET /cgi-bin/xmlcgi.pgm?db2=LP0264D
    

Check PHP Toolkit logs for messages …

  •  toolkit.ini logfile
    EDTF STMF('/usr/local/zendsvr/share/ToolkitApi/toolkit.log')
    -- or --
    call qp2term (or ssh myibmi)
    > tail /usr/local/zendsvr/share/ToolkitAPI/toolkit.log
    15 May 2012 22:53:35.752099 Running stateless; no IPC needed. Service library: ZENDSVR
    15 May 2012 22:53:36.588466 i5Error: num=14 cat=9 msg="No more entries." desc="No more entries."
    
    location set in toolkit.ini ...
    EDTF STMF('/usr/local/zendsvr/share/ToolkitApi/toolkit.ini')
    [log]
    ; warnings and errors will be written to the logfile. 
    logfile = "/usr/local/zendsvr/share/ToolkitApi/toolkit.log"
    
  •  toolkit.ini debugLogFile
    EDTF STMF('/usr/local/zendsvr/share/ToolkitApi/debug.log')
    -- or --
    call qp2term (or ssh myibmi)
    > tail /usr/local/zendsvr/share/ToolkitAPI/debug.log
    <data type='1A' var='ds1' comment='DSCHARA'><![CDATA[E]]></data>
    <data type='1A' var='ds2' comment='DSCHARB'><![CDATA[F]]></data>
    
    location set in toolkit.ini ...
    EDTF STMF('/usr/local/zendsvr/share/ToolkitApi/toolkit.ini')
    ; debug turns PHP toolkit's debug mode on or off (true/false). Default log file: /usr/local/zendsvr/share/ToolkitApi/debug.log
    ; This log will grow large, so leave this false when you do not need to log everything.
    debug = true
    debugLogFile = "/usr/local/zendsvr/share/ToolkitApi/debug.log"
    
  •  PHP and XMLSERVICE bad XML ...
    EDTF STMF('/tmp/bad.xml')
    -- or --
    > tail /tmp/bad.xml
    start
    <?xml version="1.0" encoding="ISO-8859-1" ?><script><cmd><success><&#1836;CDATA&#65533;+++ success QSYS/DLTDTAARA DTAARA(XMLSERVICE/BETTYBOOP)||></success></cmd>
    

Check one level at a time …

Troubles on your PHP site or installation???

Often times if you take a deep breath, slow down and look at each level of web site components you can find your issue without reaching for the bat phone and calling Zend or IBM. The following set of tests walks up the PHP levels of components to give you confidence you are looking at the correct layer of your issue. Of course after you complete smaller PHP scripts (hello.php, etc.), you can likely use the same step up next level techniques on your sophisticated applications (WorldPeace.php).

Level 0 — PHP working

If you are running on the IBM i machine it is always best to make sure your Apache/PHP setup can do anything.

Note: Your machine may have document root at /www/zendsvr vs. /MYASP2/www/zend2 (out-of-box installed Zend Server).

Test number #0

Install the following simple test in your Document root and see if “Hello World” appears.

/MYASP2/www/zend2/htdocs/hello.php
<?php
echo "Hello world";
?>

Run the test …

 call qp2term (or ssh myibmi)
> export PATH=/usr/local/zendsvr/bin:$PATH
> export LIBPATH=/usr/local/zendsvr/lib
> cd /MYASP2/www/zend2/htdocs
> php hello.php 
Hello world> 

No, not working???

Level 1 — Apache/PHP working

If you are running on the IBM i machine it is always best to make sure your Apache/PHP setup can do anything.

Note: Your machine may have document root at /www/zendsvr vs. /MYASP2/www/zend2 (out-of-box installed Zend Server).

Test number #1

Install the following simple test in your Document root and see if “Hello World” appears in your browser.

/MYASP2/www/zend2/htdocs/hello.php
<?php
echo "Hello world";
?>

No, not working???

Ok, next run stress test …

call qp2term
> cd /usr/local/Zend/apache2/bin
> ab -t 25 -c 10 http://myibmi/hello.php
-t 25 -- 25 seconds
-c 10 -- 10 concurrent browsers (simulates ten browsers)

wrkactjob refresh (F10) - if you do not see multiple php-cgi jobs getting CPU re-run tests with more load

call qp2term
> cd /usr/local/Zend/apache2/bin
> ab -t 25 -c 10 http://myibmi/hello.php &; ab -t 25 -c 10 http://myibmi/hello.php &; ab -t 25 -c 10 http://myibmi/hello.php &;
-t 25 -- 25 seconds
-c 10 -- 10 concurrent browsers (simulates ten browsers)
Multiply by 3 Apache ab jobs running background -- 30 concurrent browsers (simulates thirty browsers)

Level 2 — db2 connection working

At this level we want to check our DB2 connections.

Note:

Test number #2

Install the following simple test in your Document root and see if “success” appears in your browser.

/MYASP2/www/zend2/htdocs/connection2.inc
<?php
$database            = "*LOCAL"; // *LOCAL on IBM i ... LP0264D on Linux
$cwdatabase          = "localhost";
$user                = "DB2";
$password            = "XXXXXXXX";
$libxmlservice       = "ZENDSVR"; // ZZCALL (Zend Server)
$i5persistentconnect = false;
?>

/MYASP2/www/zend2/htdocs/xxtoolkit_connect.php
<?php
require_once('connection2.inc');
// flip between persistent and non-persistent connections
for ($i=0;$i<500;$i++) {
  for ($i5persistentconnect=1;$i5persistentconnect>-1;$i5persistentconnect--) {
    if ($i5persistentconnect) $conn = db2_pconnect($database,$user,$password);
    else $conn = db2_connect($database,$user,$password);
    if (!$conn) echo "<br>Bad connect: $conn,$database,$user,perm=$i5persistentconnect";
    else echo "<br>Good connect:  $conn,$database,$user,perm=$i5persistentconnect";
    if ($i5persistentconnect) $ok = true;
    else $ok = db2_close($conn);
    echo ",ok=$ok\n";
  }
}

run the test Apache …

 
Point your browser to php program ...
http://myibmi/xxtoolkit_connect.php
Good connect: Resource id #2,*LOCAL,DB2,perm=1,ok=1
Good connect: Resource id #3,*LOCAL,DB2,perm=0,ok=1
Good connect: Resource id #4,*LOCAL,DB2,perm=1,ok=1
:

run the test 2-tier … I choose to run from command line on my Linux machine, but Linux Apache would also work.

$ which php
/usr/local/zend/bin/php
$ php xxtoolkit_connect.php 
<br>Good connect:  Resource id #5,LP0264D,DB2,perm=1,ok=1
<br>Good connect:  Resource id #6,LP0264D,DB2,perm=0,ok=1
<br>Good connect:  Resource id #7,LP0264D,DB2,perm=1,ok=1
:

No, not working???

Level 3 - XMLSERVICE XML interface working

At this level we want to check our PHP raw XML Toolkit built on top of ibm_db2 connections (Level 2).

Note:

Test number #3

Install the following simple test in your Document root and see if “success” appears in your browser.

/MYASP2/www/zend2/htdocs/connection2.inc
<?php
$database            = "*LOCAL"; // *LOCAL on IBM i ... LP0264D on Linux
$cwdatabase          = "localhost";
$user                = "DB2";
$password            = "XXXXXXXX";
$libxmlservice       = "ZENDSVR"; // ZZCALL (Zend Server)
$i5persistentconnect = false;
?>

/MYASP2/www/zend2/htdocs/xxtoolkit_raw.php
<?php
require_once('connection2.inc');
if ($i5persistentconnect) $conn = db2_pconnect($database,$user,$password);
else $conn = db2_connect($database,$user,$password);
if (!$conn) echo "Bad connect: $conn,$database,$user,perm=$i5persistentconnect";

$stmt = db2_prepare($conn, "call XMLSERVICE.iPLUG4K(?,?,?,?)");
$ctl  = "*sbmjob"; // *here for no additional private job 
$ipc='/tmp/packers';
// $ipc  = "";     // *here no need ipc
$clobIn = "<?xml version='1.0'?>
<pgm name='ZZCALL' lib='$libxmlservice'>
 <parm  io='both'>
   <data type='1A'>a</data>
 </parm>
 <parm  io='both'>
   <data type='1A'>b</data>
 </parm>
 <parm  io='both'>
   <data type='7p4'>11.1111</data>
 </parm>
 <parm  io='both'>
   <data type='12p2'>222.22</data>
 </parm>
 <parm  io='both'>
  <ds>
   <data type='1A'>x</data>
   <data type='1A'>y</data>
   <data type='7p4'>66.6666</data>
   <data type='12p2'>77777.77</data>
  </ds>
 </parm>
 <return>
  <data type='10i0'>0</data>
 </return>
</pgm>";
$clobOut = "";
$ret=db2_bind_param($stmt, 1, "ipc", DB2_PARAM_IN);
$ret=db2_bind_param($stmt, 2, "ctl", DB2_PARAM_IN);
$ret=db2_bind_param($stmt, 3, "clobIn", DB2_PARAM_IN);
$ret=db2_bind_param($stmt, 4, "clobOut", DB2_PARAM_OUT);
$ret=db2_execute($stmt);
// var_dump($clobOut);
if (strpos($clobOut,"4444444444.44")>0) echo "success";
else echo "fail";
?>

run the test Apache …

 
Point your browser to php program ...
http://myibmi/xxtoolkit_raw.php
success

run the test 2-tier … I choose to run from command line on my Linux machine, but Linux Apache would also work.

$ which php
/usr/local/zend/bin/php
$ php xxtoolkit_raw.php
success

No, not working???

Ok, next run stress test …

call qp2term
> cd /usr/local/Zend/apache2/bin
> ab -t 25 -c 10 http://lp0264d/xxtoolkit_raw.php
-t 25 -- 25 seconds
-c 10 -- 10 concurrent browsers (simulates ten browsers)

Level 4 — PHP New Toolkit working

At this level we want to check our PHP CW Toolkit built on top of raw XML Toolkit (Level 3).

Note:

Test number #4

Install the following simple test in your Document root and see if “success” appears in your browser.

/MYASP2/www/zend2/htdocs/connection2.inc
<?php
$database            = "*LOCAL"; // *LOCAL on IBM i ... LP0264D on Linux
$cwdatabase          = "localhost";
$user                = "DB2";
$password            = "XXXXXXXX";
$libxmlservice       = "ZENDSVR"; // ZZCALL (Zend Server)
$i5persistentconnect = false;
?>

/MYASP2/www/zend2/htdocs/xxtoolkit_new.php
<?php
require_once('connection2.inc');
require_once("ToolkitService.php");
if ($i5persistentconnect) $conn = db2_pconnect($database,$user,$password);
else $conn = db2_connect($database,$user,$password);
if (!$conn) echo "Bad connect: $conn,$database,$user,perm=$i5persistentconnect";

try { $ToolkitServiceObj = ToolkitService::getInstance($conn); }
catch (Exception $e) { die($e->getMessage()); }
$param[] = $ToolkitServiceObj->AddParameterChar   ('both',  1,  'INCHARA', 'var1', 'Y');
$param[] = $ToolkitServiceObj->AddParameterChar   ('both',  1,  'INCHARB', 'var2', 'Z');
$param[] = $ToolkitServiceObj->AddParameterPackDec('both',  7,4,'INDEC1',  'var3', '001.0001');
$param[] = $ToolkitServiceObj->AddParameterPackDec('both', 12,2,'INDEC2',  'var4', '0000000003.04');
   $ds[] = $ToolkitServiceObj->AddParameterChar   ('both',  1,  'DSCHARA', 'ds1',  'A');
   $ds[] = $ToolkitServiceObj->AddParameterChar   ('both',  1,  'DSCHARB', 'ds2',  'B');
   $ds[] = $ToolkitServiceObj->AddParameterPackDec('both',  7,4,'DSDEC1',  'ds3',  '005.0007');
   $ds[] = $ToolkitServiceObj->AddParameterPackDec('both', 12,2,'DSDEC1',  'ds4',  '0000000006.08');
$param[] = $ToolkitServiceObj->AddDataStruct($ds);
$clobOut  = $ToolkitServiceObj->PgmCall('ZZCALL', $libxmlservice, $param, null, null);
// var_dump($clobOut);
$value = "what is ...".$clobOut["io_param"]["ds4"];
if (strpos($value,"4444444444.44")>-1) echo "success";
else echo "fail";

run the test Apache …

 
Point your browser to php program ...
http://myibmi/xxtoolkit_new.php
success

run the test 2-tier … I choose to run from command line on my Linux machine, but Linux Apache would also work.

$ which php
/usr/local/zend/bin/php
$ php xxtoolkit_new.php
success

No, not working???

Ok, next run stress test …

call qp2term
> cd /usr/local/Zend/apache2/bin
> ab -t 25 -c 10 http://lp0264d/xxtoolkit_new.php
-t 25 -- 25 seconds
-c 10 -- 10 concurrent browsers (simulates ten browsers)

Level 5 — PHP CW Toolkit working (optional)

At this level we want to check our PHP CW Toolkit built on top of new Toolkit (Level 4).

Note:

Test number #5

Install the following simple test in your Document root and see if “success” appears in your browser.

/MYASP2/www/zend2/htdocs/connection2.inc
<?php
$database            = "*LOCAL"; // *LOCAL on IBM i ... LP0264D on Linux
$cwdatabase          = "localhost";
$user                = "DB2";
$password            = "XXXXXXXX";
$libxmlservice       = "ZENDSVR"; // ZZCALL (Zend Server)
$i5persistentconnect = false;
?>

/MYASP2/www/zend2/htdocs/xxtoolkit_cw.php
<?php
require_once('connection2.inc');
require_once('CW/cw.php'); // new toolkit compatibility (Alan)

/* connect */
if ($i5persistentconnect) $conn = i5_pconnect($cwdatabase,$user,$password);
else $conn = i5_connect($cwdatabase,$user,$password);
if (!$conn) echo "Bad connect: $conn,$cwdatabase,$user,perm=$i5persistentconnect";

if (!$conn)
{ $tab = i5_error();
  die("fail Connect: ".$tab[2]." "."$tab[3], $tab[0]");
}

/* prepare */
$description = 
array
( 
  // single parms
  array
  ( "Name"=>"INCHARA","IO"=>I5_IN|I5_OUT,"Type"=>I5_TYPE_CHAR,"Length"=>"1"),
  array
  ( "Name"=>"INCHARB","IO"=>I5_IN|I5_OUT,"Type"=>I5_TYPE_CHAR,"Length"=>"1"),
  array
  ( "Name"=>"INDEC1","IO"=>I5_IN|I5_OUT,"Type"=>I5_TYPE_PACKED,"Length"=>"7.4"),
  array
  ( "Name"=>"INDEC2","IO"=>I5_IN|I5_OUT,"Type"=>I5_TYPE_PACKED,"Length"=>"12.2"),
  // structure parm 
  array
  ( "DSName"=>"INDS1",
    "Count"=>1,
    "DSParm"=>
    array
    ( 
     array
     ( "Name"=>"DSCHARA","IO"=>I5_IN|I5_OUT,"Type"=>I5_TYPE_CHAR,"Length"=>"1"),
     array
     ( "Name"=>"DSCHARB","IO"=>I5_IN|I5_OUT,"Type"=>I5_TYPE_CHAR,"Length"=>"1"),
     array
     ( "Name"=>"DSDEC1","IO"=>I5_IN|I5_OUT,"Type"=>I5_TYPE_PACKED,"Length"=>"7.4"),
     array
     ( "Name"=>"DSDEC2","IO"=>I5_IN|I5_OUT,"Type"=>I5_TYPE_PACKED,"Length"=>"12.2"),
    )
  )
);
$pgm = i5_program_prepare("$libxmlservice/ZZCALL", $description);
if (!$pgm)
{ $tab = i5_error();
  die("fail Prepare: ".$tab[2]." "."$tab[3], $tab[0]");
}

// *** parameter list allocation
$list=
array
( 
  "DSCHARA"=>"x",  
  "DSCHARB"=>"y", 
  "DSDEC1"=>66.6666,
  "DSDEC2"=>77777.77,
);
// *** parameter values passed to procedure
$in = 
array
( 
  "INCHARA"=>"a",  
  "INCHARB"=>"b", 
  "INDEC1"=>11.1111,
  "INDEC2"=>222.22,
  "INDS1"=>$list,
);
// *** name of variables created for out parameters
$out = 
array
(
  "INCHARA"=>"INCHARA",  
  "INCHARB"=>"INCHARB", 
  "INDEC1"=>"INDEC1",
  "INDEC2"=>"INDEC2",
  "INDS1"=>"INDS1",
);
$rc=i5_program_call($pgm, $in, $out);
if ($rc != false)
{
  if ($INCHARA != 'C') die("fail C == $INCHARA\n");
  if ($INCHARB != 'D') die("fail D == $INCHARB\n");
  if ($INDEC1 != 321.1234) die("fail 321.1234 == $INDEC1\n");
  if ($INDEC2 != 1234567890.12) die("fail 1234567890.12 = $INDEC2\n");
  if ($INDS1["DSCHARA"] != 'E'
  ||  $INDS1["DSCHARB"] != 'F'
  ||  $INDS1["DSDEC1"] != 333.333
  ||  $INDS1["DSDEC2"] != 4444444444.44) 
  {
    var_dump($INDS1);
    die("fail DS not correct\n");
  }

}
else
{ $tab = i5_error();
  die("fail Call: ".$tab[2]." "."$tab[3], $tab[0]");
}


// good
echo "success";
?>

run the test Apache …

 
Point your browser to php program ...
http://myibmi/xxtoolkit_cw.php
success

run the test 2-tier … I choose to run from command line on my Linux machine, but Linux Apache would also work.

$ which php
/usr/local/zend/bin/php
$ php xxtoolkit_cw.php
success

No, not working???

Ok, next run stress test …

call qp2term
> cd /usr/local/Zend/apache2/bin
> ab -t 25 -c 10 http://lp0264d/xxtoolkit_cw.php
-t 25 -- 25 seconds
-c 10 -- 10 concurrent browsers (simulates ten browsers)

Apache ab sample run

Apache ab tool — Apache ab web site stress tests are performed from the 5250 command line (call qp2term) or ssh myibmi using PASE (see Apache ab link install instructions)

Example run my machine …

> ab -t 25 -c 10 http://lp0264d/hello.php
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking lp0264d (be patient)
Completed 5000 requests
Completed 10000 requests
Completed 15000 requests
Completed 20000 requests
Finished 20325 requests


Server Software:        Apache
Server Hostname:        lp0264d
Server Port:            80

Document Path:          /hello.php
Document Length:        11 bytes

Concurrency Level:      10
Time taken for tests:   25.5119 seconds
Complete requests:      20325
Failed requests:        0
Write errors:           0
Total transferred:      3394275 bytes
HTML transferred:       223575 bytes
Requests per second:    812.83 [#/sec] (mean)    <---     800 hits/second 
Time per request:       12.303 [ms] (mean)
Time per request:       1.230 [ms] (mean, across all concurrent requests)
Transfer rate:          132.53 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   1.1      0      30
Processing:     2   11   7.2     10     322
Waiting:        2   10   7.2     10     322
Total:          2   11   7.3     11     322

Percentage of the requests served within a certain time (ms)
  50%     11
  66%     12
  75%     14
  80%     15
  90%     17
  95%     19
  98%     21
  99%     23
 100%    322 (longest request)
> 

wrkactjob — during Apache ab test you can use refresh on wrkactjob scree to see the php-cgi jobs working

                             Work with Active Jobs                     LP0264D
                                                             05/16/12  13:37:25
 CPU %:   100.0     Elapsed time:   00:00:00     Active jobs:   295

 Type options, press Enter.
   2=Change   3=Hold   4=End   5=Work with   6=Release   7=Display message
   8=Work with spooled files   13=Disconnect ...
                     Current
 Opt  Subsystem/Job  User        Type  CPU %  Function        Status
        ZEND2        QTMHHTTP    BCI      .0  PGM-zfcgi        SELW
        ZEND2        QTMHHTTP    BCI      .0  PGM-php-cgi.bi   THDW
        ZEND2        QTMHHTTP    BCI      .0  PGM-php-cgi.bi   THDW
        ZEND2        QTMHHTTP    BCI     2.8  PGM-php-cgi.bi   TIMA
        ZEND2        QTMHHTTP    BCI     1.8  PGM-php-cgi.bi   TIMA
        ZEND2        QTMHHTTP    BCI     2.3  PGM-php-cgi.bi   TIMA
        ZEND2        QTMHHTTP    BCI     2.8  PGM-php-cgi.bi   TIMA
        ZEND2        QTMHHTTP    BCI     1.8  PGM-php-cgi.bi   RUN
        ZEND2        QTMHHTTP    BCI     1.4  PGM-php-cgi.bi   TIMA

Stop XMLSERVICE for debugger attach

WRKACTJOB find XMLSERVICE private mode only

IF you are running a private connection (ipc=‘/tmp/packers’), you can simply use WRKACTJOB and locate the XMLSERVICE job and attach debugger. However the next qsysopr message option is also available.

XMLSERVICE QSYSOPR message stop anytime

At times it is useful to stop the XMLSERVICE job to connect a debugger to examine an issue, especially if you are running stateless in the QSQSRVR job.

I often find the simple trick below to be very useful.

The trick …

At this time the PHP wrappers have not implemented a stop for debugger interface (cough … Alan), but XMLSERVICE has control *debug ability already available. In the following example adding $ctl .= " *debug"; will stop XMLSERVICE job with a inquire message on qsysopr, simply attach your debugger to job # in msg, set a breakpoint in your module (or in XMLSERVICE module), and answer qsysopr message with any character to let XMLSERVICE continue to your breakpoint. That is it …

Hint: PHP wrappers are sending XML just like below, so if you have toolkit.ini debug turned on you can often simply cut/paste your XML in debug log into the variable $clobIn below.

Test #3 as example …

/MYASP2/www/zend2/htdocs/connection2.inc
<?php
$database            = "*LOCAL"; // *LOCAL on IBM i ... LP0264D on Linux
$cwdatabase          = "localhost";
$user                = "DB2";
$password            = "XXXXXXXX";
$libxmlservice       = "ZENDSVR"; // ZZCALL (Zend Server)
$i5persistentconnect = false;
?>

/MYASP2/www/zend2/htdocs/xxtoolkit_raw.php
<?php
require_once('connection2.inc');
if ($i5persistentconnect) $conn = db2_pconnect($database,$user,$password);
else $conn = db2_connect($database,$user,$password);
if (!$conn) echo "Bad connect: $conn,$database,$user,perm=$i5persistentconnect";

$stmt = db2_prepare($conn, "call XMLSERVICE.iPLUG4K(?,?,?,?)");
$ctl  = "*sbmjob";         // *here for no additional private job 
$ctl  .= " *debug";        // THIS WILL STOP XMLSERVICE JOB MSG TO QSYSOPR (server side)
// $ctl  .= " *debugproc"; // THIS WILL STOP XMLSERVICE/QSQSRVR JOB MSG TO QSYSOPR (client side)
                           // if running *here either *debug/*debugproc will work
$ipc='/tmp/packers';
// $ipc  = "";     // *here no need ipc
$clobIn = "<?xml version='1.0'?>
<pgm name='ZZCALL' lib='$libxmlservice'>
 <parm  io='both'>
   <data type='1A'>a</data>
 </parm>
 <parm  io='both'>
   <data type='1A'>b</data>
 </parm>
 <parm  io='both'>
   <data type='7p4'>11.1111</data>
 </parm>
 <parm  io='both'>
   <data type='12p2'>222.22</data>
 </parm>
 <parm  io='both'>
  <ds>
   <data type='1A'>x</data>
   <data type='1A'>y</data>
   <data type='7p4'>66.6666</data>
   <data type='12p2'>77777.77</data>
  </ds>
 </parm>
 <return>
  <data type='10i0'>0</data>
 </return>
</pgm>";
$clobOut = "";
$ret=db2_bind_param($stmt, 1, "ipc", DB2_PARAM_IN);
$ret=db2_bind_param($stmt, 2, "ctl", DB2_PARAM_IN);
$ret=db2_bind_param($stmt, 3, "clobIn", DB2_PARAM_IN);
$ret=db2_bind_param($stmt, 4, "clobOut", DB2_PARAM_OUT);
$ret=db2_execute($stmt);
// var_dump($clobOut);
if (strpos($clobOut,"4444444444.44")>0) echo "success";
else echo "fail";
?>

Hint: If $clobIn PHP XML single quote / double quote issues are driving you nuts try the following technique.

BTW — For the enterprising do-it-yourself PHP builder you can see how very easy it would be to make a custom call *PGM API with parameter substitution using str_replace() function similar to test_lib_replace() … something like function ZZCALL($INCHARA,$INCHARB,$INDEC1,$INDEC2,$INDS1)

$xml = <<<ENDPROC
<?xml version='1.0'?>
<script>
<pgm name='ZZCALL' lib='xyzlibxmlservicexyz'>
 <parm  io='both'>
   <data type='1A' var='INCHARA'>a</data>
 </parm>
 <parm  io='both'>
   <data type='1A' var='INCHARB'>b</data>
 </parm>
 <parm  io='both'>
   <data type='7p4' var='INDEC1'>11.1111</data>
 </parm>
 <parm  io='both'>
   <data type='12p2' var='INDEC2'>222.22</data>
 </parm>
 <parm  io='both'>
  <ds>
   <data type='1A' var='INDS1.DSCHARA'>x</data>
   <data type='1A' var='INDS1.DSCHARB'>y</data>
   <data type='7p4' var='INDS1.DSDEC1'>66.6666</data>
   <data type='12p2' var='INDS1.DSDEC2'>77777.77</data>
  </ds>
 </parm>
 <return>
  <data type='10i0'>0</data>
 </return>
</pgm>
</script>
ENDPROC;
$clobIn = test_lib_replace($xml);

// xml common text replacement
function test_lib_replace($xml) {
  global $libxmlservice, $iOPM;
  if (!$iOPM) {
    $was = array("xyzlibxmlservicexyz");
    $now = array("$libxmlservice");
  }
  else {
    $was = array("xyzlibxmlservicexyz","<pgm");
    $now = array("$libxmlservice","<pgm mode='opm'");
  }
  $out = str_replace($was,$now,$xml);
  return $out;
}

XMLSERVICE can be stopped …

Debug technique:
--------------
It's as easy as 1-2-3-4-5-6-7-8-9-10 :)

1. Add the following line to your PHP script before the program call to be debugged. $toolkitConn should be your toolkit connection object.
$toolkitConn->setOptions(array('customControl'=>'*debug')).

Run your script. 

The script will "hang" while it waits on #2 below...
(move to green screen 5250 for steps 2-10) 
2. A MSGW inquiry message in DSPMSG QSYSOPR will be generated by the toolkit.
3. Note the job information (number, name, user) provided in the MSGW.
4. STRSRVJOB using that job information as parameters.
5. STRDBG with the program and library you wish to debug.
6. Answer the MSGW. Any answer will do--"G" is fine.
7. The RPG program source will appear in debug mode in your terminal,
ready to step through, allowing you to inspect variables, etc.
8. When done inspecting and stepping, let the RPG program complete (using
function keys indicated on screen).
9. ENDDBG
10. ENDSRVJOB

Author(s)

Tony “Ranger” Cairns - IBM i PHP / PASE

Retrieved from http://youngiprofessionals.com/wiki/index.php/XMLService/XMLSERVICEDebug
Page last modified on October 27, 2014, at 11:10 PM EST