swoole / swoole-src

🚀 Coroutine-based concurrency library for PHP
https://www.swoole.com
Apache License 2.0
18.46k stars 3.16k forks source link

[6.0] `http_set_date_header` usage of static cache{} causes thread server to abort on `zend_string_release` #5507

Closed cjavad closed 1 month ago

cjavad commented 1 month ago

Continuing testing with threads, the static cache of http_set_date_header in ext-src/swoole_http_response.cc is not compatible when invoked from different threads.

  1. What did you do? If possible, provide a simple script for reproducing the error.

Simple echo thread server:

<?php

use Swoole\WebSocket\Server;

$server = new Server('0.0.0.0', 9501, SWOOLE_THREAD, SWOOLE_SOCK_TCP);

$server->set([
    'enable_coroutine' => true,
]);

$server->on('message', function (Server $server, $frame) {
    $server->push($frame->fd, $frame->data);
});

printf("[thread] Server started at ws://0.0.0.0:$server->port\n");
$server->start();%         

Connect and disconnect twice, or until you've made two requests on two separate threads.

To reproduce the easiest i was able to reproduce it consistently by using a continuously piping like yes together with websocat.

yes | websocat ws://0.0.0.0:9501 CTRL + C yes | websocat ws://0.0.0.0:9501

Running and cancelling these operations makes the fault appear consistently.

  1. What did you expect to see?

It should not try to release a string allocated in a different interpreter.

  1. What did you see instead?

It attempts to give the php interpreter a string to release it does not own, and a memory safety zend_mm_heap corrupted error aborts the process.

  1. What version of Swoole are you using (show your php --ri swoole)?

6.0.0 (latest master)

  1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?

Docker Alpine running Linux 6.11 + php 8.3.11 zts compiled with gcc 14.

NathanFreeman commented 1 month ago

I will take a look later.