Tag Archives: PHP on IBM I

PHP CLI on IBMi PASE Memory Limit Problem (AIX OS via QP2TERM)

I ran into one of the hardest things to figure out the dreaded “Segmentation fault” and “Illegal instruction” while running php-cli in a QP2TERM session (a PASE/AIX/”IBMs unix” shell)The exact errors were:

php-cli[9]: 12345 Illegal instruction (coredump)  –when ran non-interactive

php-cli[9]: 12345 Segmentation fault(coredump) –when ran interactive

Note: php-cli is the shell script that calls the PHP interpreter on line 9 from the command line and 12345 is the AIX process id that had the issue.  Segmentation fault means you are addressing memory outside of your data segment which has a predefined size (256MB). coredump should be a data dump in the system log

In /usr/local/zendsvr/etc/php.ini I tried to increase the
memory_limit = 512M ; Maximum amount of memory a script may consume (512M). 

I tried to set the value in my script with
ini_set(‘memory_limit’, ‘512M’); 

I even tried to set it on the command line with the -d option
/usr/local/zendsvr/bin/php-cli -d memory_limit=512M myscript.php

I figured out the amount of memory my script was using by reducing the number of records it was processing and running the follow echo command to get the peak memory usage:

echo “Memory Peak Usage: “.(memory_get_peak_usage()/1024/1024).” MB”;

The actual memory bottle neck was happening further up the chain at the AIX process/job level.  The default memory limit of AIX process is 256MB with additional Data Segments of 256MB (Hex 0x10000000 2^8) with a max size of 8 additional data segments

Solution

Set the LDR_CNTRL environment variable in the parent process (PHP-CLI) to multiple data segments (in the example below 8 additional data segments of 256MB for 2.25GB of memory [this is the max…]) and then run your php script and then unset the memory limit so you don’t affect other processes.   Modify the shell script /usr/local/zendsvr/bin/php-cli and wrap the call to the php interpreter ($ZCE_PREFIX/bin/php “$@”) with the export and unsetting of LDR_CNTRL as shown below

export LDR_CNTRL=MAXDATA=0xB0000000@DSA
$ZCE_PREFIX/bin/php “$@”
unset LDR_CNTRL

putenv should probably not work because the parent process has to set LDR_CNTRL not the PHP script

putenv(“LDR_CNTRL=MAXDATA=0xB0000000@DSA”);

Use echo getenv(“LDR_CNTRL”); to see what its set to in your PHP script.

If you are using the FASTCGI w/ apache you can modify the config file (/www/zendsvr/conf/fastcgi.conf) and add to the end of  the line starting with Server type=”application/x-httpd-php” …

SetEnv=”LDR_CNTRL=MAXDATA=0xB0000000@DSA”

Caution

If you are hitting this limit you should probably look at the program you created because there may be something that is inefficiently using memory and that should be fixed instead of changing the memory limit.

What is this DSA

“The @DSA which can be appended to this value allows the boundary been private data and shared memory to be changed, allowing more segments to be used and the heap to start in segment 3. It also allows shared objects to be moved into segment 2 to give more contiguous space (See Figure 4).” – http://ibmsystemsmag.com/CMSTemplates/IBMSystemsMag/Print.aspx?path=/aix/administrator/systemsmanagement/Avoiding-Those–Segmentation-Fault–Failure-Messag

More info here: https://www.ibm.com/support/knowledgecenter/en/ssw_aix_61/com.ibm.aix.genprogc/lrg_prg_support.htm

These issues might also go away when we go from 32 bit to 64 bit.

Advertisements

PHP IBM i toolkit – Thoughts on its future development

The PHP IBM i toolkit is a collection of PHP files that interact with XMLSERVICE on the IBM i to give you access to IBM i objects. I’ve been thinking that this approach was probably taken because it opens the doors to any programming language that wants to interact with the IBM i (PHP, Node.js, Ruby, asp.net etc… can all use this API). The problem I see with the current implementation is that requires xml encoding, xml parsing, and function calls that aren’t compiled. I think it makes sense that a PHP extension be written in C with hooks into the IBM i objects, much like how IBM_DB2.so php extension has hooks into Physical files, stored procedures, etc… IBM has C ILE that already can interact with all IBM i objects why not have a direct API to call from your PHP like db2_connect().  Your PHP project would call the compiled C PHP extension.  There’s already a starting point since you can view the source of ibm_db2.so.  Chuk from twitter mentioned creating it myself, which is tempting but unfortunately I’m not that familiar with “under the hood” of the IBM i.

IBM i PHP Toolkit

Is it all about performance? Increase in usability?

  1. There has to be a balance between performance and the ability to get the job done quickly, and easily maintainable in the future.
  2. With the PHP extension it would make it more usable as you won’t have to worry about including the CW.php wrapper.
  3. You can use the function calls provided from the php extension anywhere.
  4. Upgrades are as simple as overwriting the .so file in the php extensions folder.

Why C/C++?

  1. You can extend the functionality and performance of PHP with a compiled PHP extension.
  2. You can create C ILE on the IBM i instead of using RPG ILE.  Chris Hird says he does most of his development in C instead of RPG. If he wants to write an application on Linux he can keep using C.  RPG is proprietary and stuck on the IBM i until IBM decides to open source it.
  3. Its popular based on TIOBE rating

Alternative to toolkit to access RPG, CL programs

  1. You can create external stored procedures that attach to RPG or CL Programs (any language in drop down below)

externalproc

  1. QSYS.QCMDEXC can be called in a Stored Procedure to call CL (not sure about the other languages)
  2. The disadvantage is that you have to write and create the stored procedure for every External program.  Which is not an optimal workflow for PHP development (Write PHP, Write Stored Proc, Create Stored Proc)

What is client IBM_DB2 PHP Extension look like under the hood?

So I looked into the IBM_DB2 c source code and figured out that its more like a wrapper around SQL* ODBC functions with additional specific DB2 features added on.  So I guess that really wouldn’t be a starting point for accessing IBM i programs directly.

Responses from Twitter

TIOBE Rating

tiobeprogramming

Links

XMLSERVICE

PHP IBM i Toolkit Gihub Source

Tutorial to create PHP Extension | Another Article on PHP Extensions | More on PHP Extensions

IBM_DB2 PHP Extension Source from PECL

IBM_DB2 uses some ODBC functions and you can find info on them here

PHP Remote Debugging on Zend Server for IBM i using xdebug and Netbeans

This is a guide on how to setup xdebug on Zend Server for IBM i to use with any IDE w/ a xdebug client such as Netbeans.

Step 1  Get xdebug.so and put it on the IBM i IFS

Zend Server usually already has the file so just check that its in the

/usr/local/zendphp7/lib/php_extensions

If its not there, you can either compile your own xdebug.so by downloading the source from http://xdebug.org/ or you can just download this xdebug.so file.   Once you have the .so file you upload it to the IFS directory above.  Note on older versions of ZS the location might be:

/usr/local/zendsvr/lib/php_extensions

/usr/local/zendsvr6/lib/php_extensions

Step 2 – Setup php.ini file and other config files

You’ll also have to set

output_buffering = Off

in the php.ini.  The default for this is output_buffering=4096.  Make sure the default is commented out.

PHP.ini location: /usr/local/zendphp7/etc/php.ini

Disable Zend Debugger and Zend Optimizer

You’ll have to turn off Zend Debugger and Zend Optimizer as these files will interfere with xdebug.  To turn off this go to /usr/local/zendphp7/etc/conf.d/debugger.ini and comment out

; zend_extension_manager.dir.debugger=/usr/local/zendphp7/lib/debugger

with  a semi colon at the beggining of the line.  In older versions of Zend Server you may have to comment out optimizerplus.ini in the same directory

;zend_extension_manager.dir.optimizerplus=/usr/local/zendphp7/lib/optimizerplus

in the xdebug.ini file in the directory /usr/local/zendphp7/etc/conf.d modify it to look like the xdebug.ini below.

Step 3 – Restart Apache

On the i5/as400/iseries type:

Go ZENDPHP7/ZSMENU

Option 5 – Service Management menu

Option 6 – Stop Apache server instances

Option 5 – Start Apache server instances

or do it at https://myibmi:2010/HTTPAdmin

Step 4 – Setup xdebug client in Netbeans

Right click a project and go to project properties.  In sources, set the Web Root to the local files that map to your Web Root on the i5 (/www/zendphp7/htdocs/{myapp}).   In the Run Configuration, set up the Project URL and the index file to point to your starting index.php file.  On the toolbar menu click Tools->Options ->PHP tab-> Debugging sub tab.  At this location you can set the debugger port, session ID, if it should stop at the first line of a file, what URLs were requested and to show the debugger console.

netbeans-php-debugging-options.png

Step 5 – Launch Debugger

You lauch the debugger by pressing CTRL+F5 or by clicking the debug icon.

debug icon netbeans.png

Hopefully if everything was setup right you’ll be able to start the debugger and Netbeans will open your website up in a browser and then connect to xdebug on the server.  The way it works is the client sends the request on port 80 and then the server and the client communicate over port 9000 or the port you selected.  You’ll get all the Variables, Call stack and be able to step through the PHP code and set up Break points through out the file. If your having troubles getting this working let me know.  Running phpinfo() will also give you an idea if you’ve correctly installed xdebug.

Misc. Tips

1. You may have to move the CW wrapper for the old i5 toolkit into your project file.  You can find those files in the /usr/local/zendphp7/share/ToolkitAPI folder on the IFS.

2. You can use xdebug’s wizard that uses your phpinfo and helps you detect and install xdebug – http://xdebug.org/wizard.php

3. If your looking to compile php on the iseries this site might help – http://www.deloli.net/distrib.php

4. Netbeans wiki on how to configure xdebug  – http://wiki.netbeans.org/HowToConfigureXDebug

What phpinfo() will display about xdebug.