Asked  9 Months ago    Answers:  5   Viewed   64 times

When migrating a PHP script from PHP 5.2 to PHP 5.3, I've stumbled to the following problem: The general purpose of the script is data mining. I have a procedure inside that adds data to the MySQL server. Since it is really repetitive, I've rewritten it (a while ago) to use MySQLi, in particular prepared statements, since there are a total of 3 possible queries to perform. Anyway, now, on the PHP 5.3 server, the script is crashing on the following line:

mysqli_stmt_bind_result($prepCheck, $id1);

Where $prepCheck is created with $prepCheck = mysqli_prepare($con, $checkQuery) or die("Error");. The query runs fine on the MySQL server ($checkQuery, that is) and the PHP code was working, too, on the previous server.

Running the script with strace didn't reveal anything, since the last thing in it is the system call for echo "Execute";, which is 29936 19:44:18 write(1, "Executen", 8) = 8.

The connection object is not FALSE, and even if it was, it should fail with another error, right?

Here comes the weirdest part: This procedure does not fail when I run the script, limiting the number of pages visited and the script completes successfully. However, when I set a higher limit, it fails, always on the first call to this procedure, and precisely on this line.

If anyone has any suggestions what could be causing this, they would be deeply appreciated.

I can paste code if anyone needs to see a larger picture, but the procedure is very long and boring to death (may be that's why the script is failing :).

Here is how the script starts: error_reporting(E_ALL); ini_set('display_errors', '1');. No error is reported besides the 'magical' Segmentation fault. I'm not using APC.

Not sure if it's relevant, but I'm using CLI to run the script, not a web-interface.

PHP version is 5.3.8, MySQL version is 5.1.56. The memory limit is set to 64MB.

EDIT: The procedure failing + some of the other code is uploaded here: http://codepad.org/KkZTxttQ. The whole file is huge and ugly, and I believe irrelevant, so I'm not posting it for now. The line that's failing is 113.

 Answers

16

An answer to my own question, since I've solved the issue, and there are no other answers...

Credit goes to @jap1968 for pointing to me to the function mysqli_stmt_error (which I assumed I would not need, since I have error_reporting(E_ALL)).

The problem was that MySQL had a very weird default configuration: particularly

connect_timeout = 10
wait_timeout = 30

This caused the MySQL server to close the connection after only 30 seconds (default is more than a half hour, according to MySQL website). This in turn, caused the mysqli_stmt_bind_result function to fail with a Segmentation Fault.

Wednesday, March 31, 2021
 
OMGKurtNilsen
answered 9 Months ago
22

I solved this earlier this morning. The problem was that Yii was attempting to unregister an autoload function that didn't exist, it was likely removed in a later version of PHPUnit as I was a few minor versions ahead of my colleague. PHP throws a SIGSEGV when attempting to unregister a non-existant autoloader.

So I have changed these lines in Yii: framework/test/CTestCase.php

spl_autoload_unregister('phpunit_autoload');
Yii::registerAutoloader('phpunit_autoload');

to:

if (in_array('phpunit_autoload', spl_autoload_functions())) {
    spl_autoload_unregister('phpunit_autoload');
    Yii::registerAutoloader('phpunit_autoload');
}

This has fixed the issue. This change has already been implemented in Yii on the Git repository, but not released publicly yet. A bug report already exists on bugs.php.net too. I've answered this so it may help anyone else who has the same issue.

Saturday, May 29, 2021
 
Zach
answered 7 Months ago
11

Found the culprit... inclued.so extension was causing the problem.

I reverted back to the original osx php.ini and things worked, so I went back to the problem version of php.ini, removed one thing at a time and inclued extension was the winner!

PHP and PHPUnit now behaves quite nicely.

Saturday, May 29, 2021
 
PHLAK
answered 7 Months ago
12

Next to what cweiske suggested, if upgrading PHP is not an option for you and you have problems to locate the source of the segfault, you can use a debugger to find out more.

You can launch gdb this way to debug a PHPUnit session:

gdb --args php /usr/bin/phpunit quiz_service_Test.php

Then type in r to run the program and/or set environment variables first.

set env MALLOC_CHECK_=3
r

You might also consider to install the debugging symbols for PHP on the system to get better results for debugging. gdb checks this on startup for you and leaves a notice how you can do so.

Monday, August 9, 2021
 
Hexaholic
answered 4 Months ago
96

Congratulations; the code almost ran completely perfectly, it died on almost the final lines of code.

The issue would have been a little clearer with valgrind, but you have to be trickier running valgrind with MPI -- or anything that involves a program launcher. Instead of:

valgrind mpirun -np 10 ./exmpi_2 balloons.pgm output.pgm

which does a valgrind of mpirun, which you don't really care about, you want to do

mpirun -np 10 valgrind ./exmpi_2 balloons.pgm output.pgm

-- that is, you want to launch 10 valgrinds, each running one process' worth of exmpi_2. If you do that (and you've compiled with -g), you'll find towards the end, valgrind output like the following:

==6303==  Access not within mapped region at address 0x1
==6303==    at 0x387FA60C17: fclose@@GLIBC_2.2.5 (in /lib64/libc-2.5.so)
==6303==    by 0x401222: main (pgm.c:124)

.. and that's all there is to it; you have all processes doing the fclose()s, when only one process has a handle to a fopen()ed file in the first place. Simply replacing

fclose(FR);
fclose(FW);

with

if (rank == IONODE) {
    fclose(FR);
    fclose(FW);
}

seems to work for me.

Sunday, September 19, 2021
 
mattbilson
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share