Wednesday, August 15, 2012

Using the PHP CLI Webserver to Identify and Test Memory Issues in PHP - Christopher Jones

Using the PHP CLI Webserver to Identify and Test Memory Issues in PHP - Christopher Jones:
The PHP 5.4 CLI webserver is being used more and more to identify and
resolve PHP bugs. Following on from the CLI webserver tests that
Xinchen Hui (aka "laruence") instigated for the PHP 5.4 release,
Anatoliy Belsky (aka "weltling") begain adding CLI webserver tests for
the APC package, which is currently undergoing some much needed fixups
for PHP 5.4.


Rasmus Lerdorf has also been running some of the PHP command line
tests through the CLI web server to identify crashes and memory
corruption issues that the existing one-test-per-process tests can't
identify. Even today a fix for a session issue was merged by
Laruence. The symptom would have been a random crash that would have
been very hard to reproduce and explain to the PHP developers.


Rasmus mentioned on IRC how he ran the tests: simply renaming the
".phpt" test files as ".php", and invoking them through the CLI
webserver. The SKIPIF sections get executed, but that doesn't affect
the desired outcome of testing multiple HTTP requests with different
input scripts.

Below are some quick shell scripts I put together to automate testing
the OCI8 extension with valgrind.


There are three scripts. The first creates a copy of all OCI8 tests with
names changed to ".php":

#!/bin/sh
# NAME: setup_tests.sh
# PURPOSE: Copy .phpt files as .php
# Assumes a clean PHP-5.4 branch with no tests/*.diff files

SD=$HOME/php-5.4/ext/oci8/tests

cd /tmp && rm -rf tests && mkdir tests

for F in $(echo $SD/*)
do
if [ "${F##*.}" = "phpt" ]; then
# sym link with a .php file extension instead of .phpt
N=$(basename $F .phpt).php
else
# sym link the unchanged filename
N=$(basename $F)
fi
ln -s $F tests/$N
done


The second script starts the PHP CLI webserver:

#!/bin/sh
# NAME: start_ws.sh
# PURPOSE: Start the CLI webserver

PHP="$HOME/phpbuild/php54/sapi/cli/php"
PHPOPTS="-d max_execution_time=600 -d log_errors=Off"
PORT=4444
VALGRIND=valgrind
VALGRINDOPTS=" --tool=memcheck --suppressions=$HOME/.valgrind_supp"

USE_ZEND_ALLOC=0 $VALGRIND $VALGRINDOPTS $PHP $PHPOPTS \
-t /tmp/tests -S localhost:$PORT


Here I'm running valgrind to check for memory issues. I set the
execution time large, because several of the OCI8 tests take time,
especially with valgrind.

The third script invokes all PHP tests sequentially:

#!/bin/sh
# NAME: wg_all.sh
# PURPOSE: Load all .php scripts sequentially

PORT=4444

cd /tmp/tests

for F in *.php
do
wget -O /tmp/L.php_cli_test http://localhost:$PORT/$F
done


You can change this script to call subsets of your own scripts, or
repeatedly call scripts to check memory usage and cleanup code.


To use the scripts, start the webserver and wait for it to initialize:

$ ./start_ws.sh 
==14170== Memcheck, a memory error detector
==14170== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==14170== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==14170== Command: php -d max_execution_time=600 -d log_errors=Off -t /tmp/tests -S localhost:4444
==14170==
PHP 5.4.5-dev Development Server started at Tue Aug 14 14:53:34 2012
Listening on http://localhost:4444
Document root is /tmp/tests
Press Ctrl-C to quit.


This sits, waiting to handle requests.

In a second terminal run wg_all.sh to initiate requests:

$ ./wg_all.sh
--2012-08-14 14:38:41-- http://localhost:4444/tests/array_bind_001.php
Resolving localhost... 127.0.0.1
Connecting to localhost|127.0.0.1|:4444... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: `/tmp/L.php_cli_test'

[ <=> ] 707 --.-K/s in 0.003s

2012-08-14 14:38:44 (231 KB/s) - `/tmp/L.php_cli_test' saved [707]
. . .


You could suppress this output by adding the option "-o
/tmp/L.wg_output" to wg_all.sh. I didn't add it because, although I'm
ignoring output, I like to see that the tests are really returning
something.

The first terminal running the CLI web server shows each requested script:

[Tue Aug 14 14:35:06 2012] 127.0.0.1:34006 [200]: /tests/array_bind_001.php
[Tue Aug 14 14:35:06 2012] 127.0.0.1:34008 [200]: /tests/array_bind_002.php
[Tue Aug 14 14:35:07 2012] 127.0.0.1:34010 [200]: /tests/array_bind_003.php
[Tue Aug 14 14:35:07 2012] 127.0.0.1:34013 [200]: /tests/array_bind_004.php
[Tue Aug 14 14:35:07 2012] 127.0.0.1:34015 [200]: /tests/array_bind_005.php
[Tue Aug 14 14:35:07 2012] 127.0.0.1:34017 [200]: /tests/array_bind_006.php
[Tue Aug 14 14:35:07 2012] 127.0.0.1:

Truncated by Planet PHP, read more at the original (another 930 bytes)

DIGITAL JUICE

No comments:

Post a Comment

Thank's!