PHP Apache在执行STORED PROCEDURE时崩溃

时间:2021-12-12 06:40:49

Problem

When I execute the following code (I'm calling a stored procedure with 5 IN parameters and 1 OUT parameter)

当我执行以下代码时(我正在调用具有5个IN参数和1个OUT参数的存储过程)

$conn->query("SET @res = ''");

$mysqli=$conn;
if (!($stmt = $mysqli->prepare("CALL retrieve_matches(5,3, 16, 2, false, @res)"))) {
    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$stmt->execute()) {
    echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}

do {
    if ($res = $stmt->get_result()) { //Apache crash on this call
        printf("---\n");
        var_dump(mysqli_fetch_all($res));
        mysqli_free_result($res);
    } else {
        if ($stmt->errno) {
            echo "Store failed: (" . $stmt->errno . ") " . $stmt->error;
        }
    }
} while ($stmt->more_results() && $stmt->next_result());

apache is crashing with error:

apache崩溃错误:

AH00428: Parent: child process 9628 exited with status 255 -- Restarting.

AH00428:父级:子进程9628退出,状态为255 - 重新启动。

What I tried

  1. This code is working fine and it's returning correctly the results:
  2. 此代码工作正常,它正确返回结果:
$conn->query("SET @res = ''");
$res=$conn->query("CALL retrieve_matches(5,3, 16, 2, false, @res)");
var_dump($res->fetch_assoc());

NOTE: The same code above that make Apache crashing is working correctly if I just change the number in input of the stored procedure like:

注意:如果我只是更改存储过程的输入中的数字,上面相同的代码使Apache崩溃正常工作,如:

if (!($stmt = $mysqli->prepare("CALL retrieve_matches(5,6, 16, 2, false, @res)"))) {
  1. Tried from MySQl workbench and both calls are working fine.
  2. 从MySQl工作台尝试,两个电话都正常工作。
  3. I'm using WAMP 64b on a WIN7 Enterprise 64b, I tried with WAMP 32b but got same problem.
  4. 我在WIN7 Enterprise 64b上使用WAMP 64b,我尝试使用WAMP 32b,但遇到了同样的问题。
  5. I checked windows event and I found httpd.exe is crashing caused by php5ts.dll
  6. 我检查了Windows事件,发现httpd.exe崩溃是由php5ts.dll引起的
  7. If you search for "httpd.exe php5ts.dll" on google you can find a lot of people incountering this problem. But I didn't find a solution for WAMP...
  8. 如果你在谷歌搜索“httpd.exe php5ts.dll”,你会发现很多人遇到这个问题。但我找不到WAMP的解决方案......
  9. Tried with AMPPS, exact same problem
  10. 尝试用AMPPS,完全相同的问题

PHP Error Log

PHP错误日志

[10-Jul-2015 15:30:03 UTC] PHP Warning:  PHP Startup: Unable to load dynamic library 'C:/Program Files/wamp/bin/php/php5.5.12/ext/php_ldap.dll' - Impossibile trovare il modulo specificato.

 in Unknown on line 0

[10-Jul-2015 15:30:04 UTC] PHP Warning:  PHP Startup: Unable to load dynamic library 'C:/Program Files/wamp/bin/php/php5.5.12/ext/php_intl.dll' - Impossibile trovare il modulo specificato.

APACHE error log:

APACHE错误日志:

[Tue Jul 14 15:02:13.038276 2015] [mpm_winnt:notice] [pid 7044:tid 404] AH00428: Parent: child process 9448 exited with status 255 -- Restarting.
[Tue Jul 14 15:02:13.324305 2015] [mpm_winnt:notice] [pid 7044:tid 404] AH00455: Apache/2.4.9 (Win32) PHP/5.5.12 configured -- resuming normal operations
[Tue Jul 14 15:02:13.329306 2015] [mpm_winnt:notice] [pid 7044:tid 404] AH00456: Apache Lounge VC11 Server built: Mar 16 2014 12:13:13
[Tue Jul 14 15:02:13.329306 2015] [core:notice] [pid 7044:tid 404] AH00094: Command line: 'C:\\Program Files\\wamp\\bin\\apache\\apache2.4.9\\bin\\httpd.exe -d C:/Program Files/wamp/bin/apache/apache2.4.9'
[Tue Jul 14 15:02:13.352308 2015] [mpm_winnt:notice] [pid 7044:tid 404] AH00418: Parent: Created child process 3140
[Tue Jul 14 15:02:14.528388 2015] [mpm_winnt:notice] [pid 3140:tid 332] AH00354: Child: Starting 64 worker threads.

I'm really lost here, where should I look for the issue? Thanks very much for your help

我真的迷失在这里,我应该在哪里寻找这个问题?非常感谢您的帮助

EDIT

编辑

I realized that the stored procedure "retrieve_matches" is calling different stored procedure in function of the changed value. I debugged the stored procedure "retrieve_standalone" that is the one that make Apache crashing. This procedure is doing select/insert, I checked and the insert are made correctly. BUT inside "retrieve_standalone" I'm using a cursor in a weird way:

我意识到存储过程“retrieve_matches”正在根据更改的值调用不同的存储过程。我调试了存储过程“retrieve_standalone”,这是使Apache崩溃的过程。此过程正在执行select / insert,我检查并正确插入。但是在“retrieve_standalone”里面,我正在以一种奇怪的方式使用游标:

declare bNoMoreRows bool default false;
declare tmp_cursor cursor for
    select comp_id from to_match; -- to_match is a temporary table
declare continue handler for not found set bNoMoreRows := true;

if I don't open the cursor

如果我不打开光标

open tmp_cursor;

everything is working fine!! So I guess I found the issue, now: how can I solve it?

一切都很好!!所以我想我现在发现了这个问题:我怎么解决呢?

5 个解决方案

#1


1  

Apparently there's a bit of buck passing - i.e. scaricabarile - between PHP guys and MySQLi guys.

显然,在PHP家伙和MySQLi家伙之间有一些推卸责任 - 即scaricabarile。

What seems to be happening is that MySQLi reacts in an "improper" way, and return an unexpected value (I'd bet a small sum on it being a NULL) to PHP, which duly coredumps. This behaviour is documented and the verdict from PHPland is: "Not a [PHP] bug". On their side, the MySQLi guys maintain that it's PHP which is not correctly checking the returned result. And that 'improper' results depended on your query anyway.

似乎正在发生的事情是,MySQLi以一种“不正当”的方式作出反应,并向PHP返回一个意外的值(我敢打赌它是一个小小的余额),这是正确的coredumps。记录了这种行为,来自PHPland的判决是:“不是[PHP]错误”。在他们这边,MySQLi的人坚持认为它是PHP没有正确检查返回的结果。无论如何,“不正确”的结果取决于您的查询。

So I'm going out on a limb and supposing that yours is the same problem of "communication difficulties", so the problem becomes: "Your query forces MySQLi to drop/reconnect". Why is that so? Apparently (some) stored procedures require mysqli_multi_query in order to behave properly.

因此,我要走出困境并假设你的问题与“通信困难”相同,所以问题就变成:“你的查询迫使MySQLi掉线/重新连接”。为什么?显然(某些)存储过程需要mysqli_multi_query才能正常运行。

And mysqli_multi_query is not compatible with mysqli_prepare.

并且mysqli_multi_query与mysqli_prepare不兼容。

So I'd suggest trying without preparing the query, and running it with mysqli_multi_query.

因此,我建议在不准备查询的情况下进行尝试,并使用mysqli_multi_query运行它。

$conn->query("SET @res = ''");
$conn->multi_query("CALL retrieve_matches(5,3, 16, 2, false, @res)");

do {
    if ($result = $conn->store_result()) {
        while ($row = $result->fetch_row()) {
            var_dump($row);
        }
        $result->free();
    }
} while ($conn->more_results() && $conn->next_result());

With this code, your test case gets me, as expected,

有了这段代码,你的测试用例就像我们预期的那样得到了我

array(1) {
  [0] =>
  string(4) "test"
}

#2


6  

If php5ts.dll, or any other part of apache crashes in a reproducible way every time you run a short script, you have most likely hit a bug in php. Especially if you run an up-to-date apache with a recent php-version downloaded from php.net you have a very good chance of getting support from the PHP team. So read through https://bugs.php.net/how-to-report.php, see if you can reproduce the crash when running the script without apache (in a separate script on the cli using php.exe) and generate a backtrace which you can then submit as a bug.

如果php5ts.dll或apache的任何其他部分每次运行一个简短的脚本时都以可重现的方式崩溃,那么你很可能在php中遇到了一个bug。特别是如果您使用从php.net下载的最新php版本运行最新的apache,您很有可能获得PHP团队的支持。所以通过https://bugs.php.net/how-to-report.php阅读,看看你是否可以在没有apache运行脚本时重现崩溃(在使用php.exe的cli上的单独脚本中)并生成一个您可以将其作为错误提交的回溯。

Bugs like these can sometimes be worked around but rarely be fixed from the context of your script. PHP should never crash the webserver and if it does this reproducibly a bug should be filed so it can be fixed

像这样的错误有时可以解决,但很少从脚本的上下文中修复。 PHP永远不应该崩溃网络服务器,如果它可以重现,那么应该提交一个bug,以便修复它

#3


3  

I find out how to reproduce it, I believe it's a php/apache bug

我发现如何重现它,我相信这是一个php / apache bug

PHP code:

PHP代码:

if (!($stmt = $mysqli->prepare("CALL test()"))) {
    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$stmt->execute()) {
    echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}

do {
    if ($res = $stmt->get_result()) {
        printf("---\n");
        //var_dump(mysqli_fetch_all($res));
        var_dump($res->fetch_assoc());
        mysqli_free_result($res);
    } else {
        if ($stmt->errno) {
            echo "Store failed: (" . $stmt->errno . ") " . $stmt->error;
        }
    }
} while ($stmt->more_results() && $stmt->next_result());

Store procedure code:

存储过程代码:

CREATE DEFINER=`root`@`localhost` PROCEDURE `test`()
BEGIN
declare test_var varchar(100) default "ciao";
declare bNoMoreRows bool default false;
declare test_cursor cursor for
    select id from tmp_folder;
declare continue handler for not found set bNoMoreRows := true;

create temporary table tmp_folder select "test" as id;

open test_cursor;

fetch test_cursor into test_var;

close test_cursor;

select test_var;

drop temporary table if exists tmp_folder;

END

Bug opened: Apache: https://bz.apache.org/bugzilla/show_bug.cgi?id=58136

错误打开:Apache:https://bz.apache.org/bugzilla/show_bug.cgi?id = 58136

Php: https://bugs.php.net/bug.php?id=70073

Php:https://bugs.php.net/bug.php?id = 70073

#4


1  

I think you are confusing $conn and $stmt. Here is what I have. (It gathers the result into $out.)

我认为你让$ conn和$ stmt感到困惑。这就是我所拥有的。 (它将结果收集到$ out。)

if ($conn->multi_query($call)) {
    $raa = array();
    do {
        /* store first result set */
        if ($result = $conn->use_result()) {
            while ($row = $result->fetch_row()) {
                $raa[] = $row;
                printf("+\n");
            }
            $result->close();
        }
        $out[] = $raa;
        /* print divider */
        if ($conn->more_results()) {
            printf("-----------------\n");
        }
    } while ($conn->next_result());
}
else
    echo "err";

#5


-1  

Try changing your server stack. Either upgrade WAMP or run your code in a different environment. This question suggests there is a bug in WAMP that will cause Apache to throw the 255 error

尝试更改服务器堆栈。升级WAMP或在不同的环境中运行代码。这个问题表明WAMP中存在一个错误,会导致Apache抛出255错误

php -> mysql_connect -> child process exited with status 255 -- Restarting

php - > mysql_connect - >子进程退出状态为255 - 重新启动

#1


1  

Apparently there's a bit of buck passing - i.e. scaricabarile - between PHP guys and MySQLi guys.

显然,在PHP家伙和MySQLi家伙之间有一些推卸责任 - 即scaricabarile。

What seems to be happening is that MySQLi reacts in an "improper" way, and return an unexpected value (I'd bet a small sum on it being a NULL) to PHP, which duly coredumps. This behaviour is documented and the verdict from PHPland is: "Not a [PHP] bug". On their side, the MySQLi guys maintain that it's PHP which is not correctly checking the returned result. And that 'improper' results depended on your query anyway.

似乎正在发生的事情是,MySQLi以一种“不正当”的方式作出反应,并向PHP返回一个意外的值(我敢打赌它是一个小小的余额),这是正确的coredumps。记录了这种行为,来自PHPland的判决是:“不是[PHP]错误”。在他们这边,MySQLi的人坚持认为它是PHP没有正确检查返回的结果。无论如何,“不正确”的结果取决于您的查询。

So I'm going out on a limb and supposing that yours is the same problem of "communication difficulties", so the problem becomes: "Your query forces MySQLi to drop/reconnect". Why is that so? Apparently (some) stored procedures require mysqli_multi_query in order to behave properly.

因此,我要走出困境并假设你的问题与“通信困难”相同,所以问题就变成:“你的查询迫使MySQLi掉线/重新连接”。为什么?显然(某些)存储过程需要mysqli_multi_query才能正常运行。

And mysqli_multi_query is not compatible with mysqli_prepare.

并且mysqli_multi_query与mysqli_prepare不兼容。

So I'd suggest trying without preparing the query, and running it with mysqli_multi_query.

因此,我建议在不准备查询的情况下进行尝试,并使用mysqli_multi_query运行它。

$conn->query("SET @res = ''");
$conn->multi_query("CALL retrieve_matches(5,3, 16, 2, false, @res)");

do {
    if ($result = $conn->store_result()) {
        while ($row = $result->fetch_row()) {
            var_dump($row);
        }
        $result->free();
    }
} while ($conn->more_results() && $conn->next_result());

With this code, your test case gets me, as expected,

有了这段代码,你的测试用例就像我们预期的那样得到了我

array(1) {
  [0] =>
  string(4) "test"
}

#2


6  

If php5ts.dll, or any other part of apache crashes in a reproducible way every time you run a short script, you have most likely hit a bug in php. Especially if you run an up-to-date apache with a recent php-version downloaded from php.net you have a very good chance of getting support from the PHP team. So read through https://bugs.php.net/how-to-report.php, see if you can reproduce the crash when running the script without apache (in a separate script on the cli using php.exe) and generate a backtrace which you can then submit as a bug.

如果php5ts.dll或apache的任何其他部分每次运行一个简短的脚本时都以可重现的方式崩溃,那么你很可能在php中遇到了一个bug。特别是如果您使用从php.net下载的最新php版本运行最新的apache,您很有可能获得PHP团队的支持。所以通过https://bugs.php.net/how-to-report.php阅读,看看你是否可以在没有apache运行脚本时重现崩溃(在使用php.exe的cli上的单独脚本中)并生成一个您可以将其作为错误提交的回溯。

Bugs like these can sometimes be worked around but rarely be fixed from the context of your script. PHP should never crash the webserver and if it does this reproducibly a bug should be filed so it can be fixed

像这样的错误有时可以解决,但很少从脚本的上下文中修复。 PHP永远不应该崩溃网络服务器,如果它可以重现,那么应该提交一个bug,以便修复它

#3


3  

I find out how to reproduce it, I believe it's a php/apache bug

我发现如何重现它,我相信这是一个php / apache bug

PHP code:

PHP代码:

if (!($stmt = $mysqli->prepare("CALL test()"))) {
    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$stmt->execute()) {
    echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}

do {
    if ($res = $stmt->get_result()) {
        printf("---\n");
        //var_dump(mysqli_fetch_all($res));
        var_dump($res->fetch_assoc());
        mysqli_free_result($res);
    } else {
        if ($stmt->errno) {
            echo "Store failed: (" . $stmt->errno . ") " . $stmt->error;
        }
    }
} while ($stmt->more_results() && $stmt->next_result());

Store procedure code:

存储过程代码:

CREATE DEFINER=`root`@`localhost` PROCEDURE `test`()
BEGIN
declare test_var varchar(100) default "ciao";
declare bNoMoreRows bool default false;
declare test_cursor cursor for
    select id from tmp_folder;
declare continue handler for not found set bNoMoreRows := true;

create temporary table tmp_folder select "test" as id;

open test_cursor;

fetch test_cursor into test_var;

close test_cursor;

select test_var;

drop temporary table if exists tmp_folder;

END

Bug opened: Apache: https://bz.apache.org/bugzilla/show_bug.cgi?id=58136

错误打开:Apache:https://bz.apache.org/bugzilla/show_bug.cgi?id = 58136

Php: https://bugs.php.net/bug.php?id=70073

Php:https://bugs.php.net/bug.php?id = 70073

#4


1  

I think you are confusing $conn and $stmt. Here is what I have. (It gathers the result into $out.)

我认为你让$ conn和$ stmt感到困惑。这就是我所拥有的。 (它将结果收集到$ out。)

if ($conn->multi_query($call)) {
    $raa = array();
    do {
        /* store first result set */
        if ($result = $conn->use_result()) {
            while ($row = $result->fetch_row()) {
                $raa[] = $row;
                printf("+\n");
            }
            $result->close();
        }
        $out[] = $raa;
        /* print divider */
        if ($conn->more_results()) {
            printf("-----------------\n");
        }
    } while ($conn->next_result());
}
else
    echo "err";

#5


-1  

Try changing your server stack. Either upgrade WAMP or run your code in a different environment. This question suggests there is a bug in WAMP that will cause Apache to throw the 255 error

尝试更改服务器堆栈。升级WAMP或在不同的环境中运行代码。这个问题表明WAMP中存在一个错误,会导致Apache抛出255错误

php -> mysql_connect -> child process exited with status 255 -- Restarting

php - > mysql_connect - >子进程退出状态为255 - 重新启动