Swoole-src: coroutine http client /usr/src/swoole-src-master/src/network/Client.c:457: swClient_close: Assertion `fd != 0' failed.

Created on 3 Jul 2018  ·  9Comments  ·  Source: swoole/swoole-src

Please answer these questions before submitting your issue. Thanks!

  1. What did you do? If possible, provide a recipe for reproducing the error.
    php test.php
    运行后多等待几秒钟。
Swoole http server is started at http://0.0.0.0:9501
[2018-07-04 12:59:01 $767.0]    WARNING swManager_check_exit_status: worker#0 abnormal exit, status=0, signal=11
php: /usr/src/swoole-src-master/src/network/Client.c:457: swClient_close: Assertion `fd != 0' failed.
[2018-07-04 12:59:04 $767.0]    WARNING swManager_check_exit_status: worker#0 abnormal exit, status=0, signal=6
php: /usr/src/swoole-src-master/src/network/Client.c:457: swClient_close: Assertion `fd != 0' failed.
[2018-07-04 12:59:06 $767.0]    WARNING swManager_check_exit_status: worker#0 abnormal exit, status=0, signal=6

重现代码:

<?php
function buildCli($url, array $header = [], array $setting = ['timeout' => 5]) {
    if(! preg_match('/^https?:\/\//isU', $url)) {
        $url = 'http://' . $url;
    }

    $url_info = parse_url($url);

    $is_https = isset($url_info ['scheme']) && strpos($url_info ['scheme'], 'https') !== false;

    if(empty($url_info ['port'])) {
        $url_info ['port'] = $is_https ? 443 : 80;
    }

    $cli = new \Swoole\Coroutine\Http\Client($url_info ['host'], $url_info ['port'], $is_https);
    $cli->set($setting);

    //请求path保存为属性
    $cli->exec_path = preg_replace('/[^\/]*(\/\/)?' . $url_info ['host'] . '(:\d+)?\//isU', '/', $url);

    //有header时需要setHeaders,
    if(! empty($header)) {
        //header无Host时,需要补全。
        if(empty($header ['Host'])) {
            $header ['Host'] = $url_info ['host']; // 设置request_header Host
        }
        $cli->setHeaders($header);
    }

    return $cli;
}
function buildClient($url, $method = 'GET', $data = '', array $header = [], $defer = false) {
    $header = array_merge([ 
            'Connection' => 'close',
            "User-Agent" => 'Chrome/49.0.2587.3',
            "Charset" => "UTF-8",
            "Content-Type" => "application/json",
            'Accept' => 'text/html,application/xhtml+xml,application/xml,application/json',
            'Accept-Encoding' => 'gzip' 
    ], $header);

    $cli = buildCli($url, $header);

    $cli->setMethod(strtoupper($method));

    $cli->setData($data);

    // 延迟收包
    if($defer) {
        $cli->setDefer();
    }

    $cli->execute($cli->exec_path);

    if(! $defer) {
        //$cli->close();
    }

    return $cli;
}

$http = new swoole_http_server("0.0.0.0", 9501);

$http->on("start", function ($server) {
    echo "Swoole http server is started at http://0.0.0.0:9501\n";
});
$http->on('WorkerStart', function (\swoole_http_server $server, $worker_id) {
    if($worker_id == 0) {
        $data='{"token":"test","message_type":"123","send_data_template":{"touser":"abc"},"user_list":{"user":["abc","abc","abc"]}}';
        go(function () use ($data) {
            $data = json_decode($data, TRUE);
            $template_data = $data ['send_data_template'];
            $count = count($data ['user_list'] ['user']);

            $success = 0;

            $offset = 0;
            $number = 50;

            while ($offset < $count) {
                $url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=';
                //初始化client box
                $cli_box = [ ];
                for($i = $offset; $i < $offset + $number && $i < $count; $i ++) {

                    $template_data ['touser'] = $data ['user_list'] ['user'] [$i];

                    $cli_box [] = buildClient($url, 'POST', json_encode($template_data, JSON_UNESCAPED_UNICODE), [ ], true);
                }

                //并发请求
                foreach ( $cli_box as $key => $cli ) {
                    $cli->recv();
                    //特殊情况下,需要重新请求,此处判断只是为了重现问题
                    if($cli->body) {
                        //$cli变量被覆盖=>导致问题
                        $cli = buildClient($url, 'POST', json_encode($template_data, JSON_UNESCAPED_UNICODE));
                    }
                }

                $offset += $number;
            }
        });
    }
});

$http->on("request", function ($request, $response) {
    $response->header("Content-Type", "application/json");
    $response->end('{"code":"200","msg":"ok"}');
});

$http->start();
  1. What did you expect to see?

  2. What did you see instead?
    发帖时master分支最新版
    issuse #1750 的问题仍然会出现

/usr/src/swoole-src-master/src/network/Client.c:457: swClient_close: Assertion `fd != 0' failed.
[2018-07-03 11:54:53 $44384.0]  WARNING swManager_check_exit_status: worker#0 abnormal exit, status=0, signal=6

gbd调试信息

gdb php core.44389 
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from php...done.
[New LWP 44389]
[New LWP 44393]
[New LWP 44394]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `taskboy_worker'.
Program terminated with signal SIGABRT, Aborted.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51  ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
[Current thread is 1 (Thread 0x7fa85df35b80 (LWP 44389))]
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007fa857e8642a in __GI_abort () at abort.c:89
#2  0x00007fa857e7de67 in __assert_fail_base (fmt=<optimized out>, assertion=assertion@entry=0x7fa852ad6a30 "fd != 0", file=file@entry=0x7fa852ad6838 "/usr/src/swoole-src-master/src/network/Client.c", 
    line=line@entry=457, function=function@entry=0x7fa852ad6b48 <__PRETTY_FUNCTION__.24564> "swClient_close") at assert.c:92
#3  0x00007fa857e7df12 in __GI___assert_fail (assertion=assertion@entry=0x7fa852ad6a30 "fd != 0", file=file@entry=0x7fa852ad6838 "/usr/src/swoole-src-master/src/network/Client.c", line=line@entry=457, 
    function=function@entry=0x7fa852ad6b48 <__PRETTY_FUNCTION__.24564> "swClient_close") at assert.c:101
#4  0x00007fa852aaefd4 in swClient_close (cli=<optimized out>) at /usr/src/swoole-src-master/src/network/Client.c:457
#5  0x00007fa852a83e35 in zim_swoole_http_client_coro_close (execute_data=0x7fa85349dd00, return_value=0x55b27d2a3660) at /usr/src/swoole-src-master/swoole_http_client_coro.c:1740
#6  0x000055b27ab19904 in zend_call_function ()
#7  0x000055b27ab48c8f in zend_call_method ()
#8  0x00007fa852a875e1 in zim_swoole_http_client_coro___destruct (execute_data=0x7fa85349dcb0, return_value=<optimized out>) at /usr/src/swoole-src-master/swoole_http_client_coro.c:1387
#9  0x000055b27ab19904 in zend_call_function ()
#10 0x000055b27ab48c8f in zend_call_method ()
#11 0x000055b27ab63fc2 in zend_objects_destroy_object ()
#12 0x000055b27ab6932b in zend_objects_store_del ()
#13 0x000055b27abd0d4c in zend_leave_helper_SPEC ()
#14 0x000055b27abd661b in execute_ex ()
#15 0x00007fa852aa19ab in swoole::Context::context_func (arg=0x55b27d0a39f0) at /usr/src/swoole-src-master/src/coroutine/context.cc:66
#16 0x00007fa852ac8511 in make_fcontext () at /usr/src/swoole-src-master/thirdparty/boost/asm/make_x86_64_sysv_elf_gas.S:64
#17 0x0000000000000000 in ?? ()
(gdb) f
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51  in ../sysdeps/unix/sysv/linux/raise.c
  1. What version of Swoole are you using (php --ri swoole)?
    发帖时,master分支最新版
swoole

swoole support => enabled
Version => 4.0.1
Author => tianfeng.han[email: [email protected]]
coroutine => enabled
epoll => enabled
eventfd => enabled
timerfd => enabled
signalfd => enabled
cpu affinity => enabled
spinlock => enabled
rwlock => enabled
async http/websocket client => enabled
openssl => enabled
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled

Directive => Local Value => Master Value
swoole.aio_thread_num => 2 => 2
swoole.display_errors => On => On
swoole.use_namespace => On => On
swoole.use_shortname => On => On
swoole.fast_serialize => Off => Off
swoole.unixsock_buffer_size => 8388608 => 8388608
bug coroutine fixed

Most helpful comment

@8923052 请拉一下最新的代码, 没有断言错误了, 请看看脚本运行是否符合预期

All 9 comments

@8923052 是否复用了并发请求的客户端?

@twose 没有复用,每次都是新创建的client,defer机制并发请求。

@8923052 我这没有这个情况, 不好定位, 能否贴复现代码

@8923052 请提供一份可以稳定重现的php代码吧

我想想办法,项目代码没法给,我需要多测试一下问题怎么复现。。。

@8923052 针对这个情况,我现在又加了一些防御性编程代码,你重新 git pull 然后 make clean && make install,再看看是否可以重现。现在最好是能找到一个可重现的案例,我们做成单元测试脚本。

@matyhtf 已剥离出部分代码,可以重现,补充在上面帖子中了,其中一行代码覆盖client变量时会引起该问题。

Swoole http server is started at http://0.0.0.0:9501
[2018-07-04 12:59:01 $767.0]    WARNING swManager_check_exit_status: worker#0 abnormal exit, status=0, signal=11
php: /usr/src/swoole-src-master/src/network/Client.c:457: swClient_close: Assertion `fd != 0' failed.
[2018-07-04 12:59:04 $767.0]    WARNING swManager_check_exit_status: worker#0 abnormal exit, status=0, signal=6
php: /usr/src/swoole-src-master/src/network/Client.c:457: swClient_close: Assertion `fd != 0' failed.
[2018-07-04 12:59:06 $767.0]    WARNING swManager_check_exit_status: worker#0 abnormal exit, status=0, signal=6

麻烦您看看。

@8923052 请拉一下最新的代码, 没有断言错误了, 请看看脚本运行是否符合预期

@twose 已测试,未发现问题,感谢!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zuozhehao picture zuozhehao  ·  3Comments

sshymko picture sshymko  ·  3Comments

chenye2017 picture chenye2017  ·  3Comments

jerryli1 picture jerryli1  ·  4Comments

kings36503 picture kings36503  ·  3Comments