amphp / http-client

An advanced async HTTP client library for PHP, enabling efficient, non-blocking, and concurrent requests and responses.
https://amphp.org/http-client
MIT License
704 stars 66 forks source link

v5: segmentation fault (SIGPIPE using gdb) requesting some urls #309

Closed maxgalbu closed 1 year ago

maxgalbu commented 2 years ago

The following script sometimes throws "Segmentation fault" GDB shows this error when running the same script:

alpine: Program received signal SIGPIPE, Broken pipe. 0x00007fafa0dc44a3 in ?? () from /lib/ld-musl-x86_64.so.1

wheezy: Program received signal SIGPIPE, Broken pipe. 0x00007f5757905fb3 in __libc_write (fd=8, buf=0x560a390f44d3, nbytes=24) at ../sysdeps/unix/sysv/linux/write.c:26

<?php

use Amp\Future;
use Amp\Http\Client\HttpClientBuilder;
use Amp\Http\Client\HttpException;
use Amp\Http\Client\Request;
use function Amp\async;

require(__DIR__. "/../../vendor/autoload.php");

$uris = [
    "https://google.com/",
    "https://jsonplaceholder.typicode.com/todos/1",
    "https://nonexistingdomainwtfisthis.com",
];

// Instantiate the HTTP client
$client = HttpClientBuilder::buildDefault();

$requestHandler = static function (string $uri) use ($client): string {
    $request = new Request($uri);
    $request->setHeader("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/81.0");

    $response = $client->request($request);
    return $response->getBody()->buffer();
};

try {
    $startGlobal = microtime(true);

    $futures = [];
    foreach ($uris as $uri) {
        $futures[$uri] = async(function () use ($requestHandler, $uri) {
            try {
                $start = microtime(true);
                $future = async(fn() => $requestHandler($uri));
                $response = $future->await();
                $end = microtime(true) - $start;

                print $uri . " - " . strlen($response) . " bytes after $end seconds" . PHP_EOL;
            } catch (\Exception $error) {
                printf("%s: %s\n", "test", $error->getMessage());
            }
        });
    }

    $ignore = Future\await($futures);

    $endGlobal = microtime(true) - $startGlobal;
    print "Finished after $endGlobal seconds" . PHP_EOL;
} catch (HttpException $error) {
    // If something goes wrong Amp will throw the exception where the promise was yielded.
    // The HttpClient::request() method itself will never throw directly, but returns a promise.
    var_dump($error);
}
php -v and php -m ``` bash-5.1# php -v PHP 8.1.12 (cli) (built: Nov 16 2022 20:54:15) (ZTS) Copyright (c) The PHP Group Zend Engine v4.1.12, Copyright (c) Zend Technologies with Zend OPcache v8.1.12, Copyright (c), by Zend Technologies bash-5.1# php -m [PHP Modules] Core ctype curl date dom fileinfo filter ftp hash iconv json libxml mbstring mysqlnd openssl pcntl pcre PDO pdo_mysql pdo_sqlite Phar posix readline redis Reflection session SimpleXML sodium SPL sqlite3 standard tokenizer xml xmlreader xmlwriter Zend OPcache zlib [Zend Modules] Zend OPcache ```
maxgalbu commented 2 years ago

Ignoring SIGPIPE shows no error in gdb. Disabling opcache makes the error disappear... probably?

kelunik commented 1 year ago

Please retry with the latest PHP versions and version of this library. There have been a few critical fiber bugs.