Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Publish/subscribe (Segmentation fault) #4

Closed
talexander opened this Issue · 17 comments

8 participants

@talexander

This small script crache php.

function f($redis, $chan, $msg) {
echo "Handle message " . $msg . ' for chanel ' . $chan;
}

$r = new Redis();
if($r->connect('127.0.0.1', 6379)) {
echo 'Sleepping' . PHP_EOL;
sleep(5);

$chanel = 'chanel_'  . rand(1, 10);
echo 'Subscribe  to chanel ' . $chanel . PHP_EOL;
$r->subscribe(array($chanel), 'f');

/* for($i = 0; $i < 10; $i++) {
$r->publish('chanel_' . $i, 'test msg ' . rand(1, 10));
}*/

/*
for($i = 1; $i < 100; $i++) {
    echo $i . PHP_EOL;
    usleep(100000);
}
*/

} else {
echo "Can`t connect to redis." . PHP_EOL;
}

@nicolasff
Owner

Hello,

I can reproduce this issue, although I'm not really sure what behaviour you expect (apart from not crashing, of course). You connect to Redis with a timeout of 2.5 seconds, and sleep for 5 seconds.

What do you think should happen? Should subscribe just return?

@talexander

SEGFAULT occurs even when timeout is not defined. In this simple script i want to know whether the interrupted thread of execution or or will meet the following asynchronous code. Sorry for my english :)

@vkartaviy

I have the same issue running the following code:

$redis = new Redis();

echo 'Trying to connect to 127.0.0.1:6379' . PHP_EOL;
if ($redis->connect('127.0.0.1', 6379)){

    $channel = 'CHAT'; 

    echo 'Trying to subscribe to the channel named ' . $channel . PHP_EOL;
    function handle_message($redis, $channel, $message){
        echo 'Handle message ' . $message . ' for the channel ' . $channel . PHP_EOL;
    }
    $redis->subscribe(array($channel), 'handle_message');

} else {
    echo 'Can`t connect to 127.0.0.1:6379' . PHP_EOL;
}
@nicolasff
Owner

@talexander: it is not asynchronous, but synchronous. The call is blocking until a message is received.

@vkartaviy: Are you running on 32 or 64 bits? Thanks.

@vkartaviy

I`am using version 2.1.0 with PHP 5.3.6 on Debian 2.6.32-5-amd64

@nicolasff nicolasff was assigned
@Jmoati

Hello.
Segmentation fault too with Ubuntu 11.04 x64, PHP 5.3.5 and redis 2.2.7.

Log says :

May 19 16:27:10 devbox kernel: [757859.258332] php[10198]: segfault at 14 ip 00007f646240f3e6 sp 00007fffec59a610 error 4 in redis.so[7f6462406000+2e000]

I hope it will help you.

@Jmoati

English

Hello.
Same problem on Ubuntu 10.04.2 LTS i686, PHP 5.3.2 and redis 2.2.7.
It's not 64 bits the problem...

When I run the connection with

$redis->connect('127 .0.0.1 ', '6379', 0);
or
$redis->connect('127 .0.0.1 ', '6379');
, I get a Segmentation fault after 60 seconds (without activity).

So when I start with the

$redis->connect('127 .0.0.1 ', '6379', 120);
, the segmentation fault occurs after 120 seconds (without activity).

For now, I put

$redis->connect('127.0.0.1', '6379', 600000000);

which should let me around 19 years old timeout :)

I hope it will help you.


French

Bonjour,

Même problème avec Ubuntu 10.04.2 LTS i686, PHP 5.3.2 et redis 2.2.7.
Ce n'est donc pas l'architecture 64bits le problème ...

Par contre,
Quand je lance la connexion avec

$redis->connect('127.0.0.1', '6379', 0);
ou
$redis->connect('127.0.0.1', '6379');
, j'obtient un Segmentation fault au bout de 60 secondes (sans activité).

Alors que quand je la lance avec

$redis->connect('127.0.0.1', '6379', 120);
, le Segmentation fault intervient au bout de 120 secondes (sans activité).

Pour le moment, je met

$redis->connect('127.0.0.1', '6379', 600000000);

qui devrait me laisser environs 19ans de timeout :)

J’espère que celà pourra vous aider ...

@starjiang

when redis timeout
z_tab = redis_sock_read_multibulk_reply_zval(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock);
the z_tab is NULL,but not judge it,so
if(Z_TYPE_P(z_tab) != IS_ARRAY) {
coredump

edit redis.c
line to 4768

    if(z_tab==NULL)
    {
        break;
    }
    if(Z_TYPE_P(z_tab) != IS_ARRAY) {
        //ERROR
        break;
    }

rebuild your redis.so

try
{
echo $redis->subscribe(array('chanel1'),'cb');
}
catch(RedisException $e)
{
echo $e->getMessage();
//here reconnect and continue subscribe
}
~

@nicolasff nicolasff referenced this issue from a commit
@nicolasff nicolasff Fix Github issue #4 c0dbf8c
@nicolasff
Owner

@starjiang thanks, good catch.

@vavr

I have installed a phpredis extention from master branch.
After subscribe method called, script always crached after 60 seconds.

exception 'RedisException' with message 'read error on connection' in test.php:10
Stack trace:
#0 /srv/www/test.php(10): Redis->subscribe(Array, 'f')

The test script:
function f($redis, $chan, $msg){
var_dump($chan);
var_dump($msg);
}

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);// variant $redis->connect('127.0.0.1', 6379, 0); also crashed the script
$redis->subscribe(array('root'),'f');

OS Ubuntu 11.10
$ php --version
PHP 5.3.6-13ubuntu3.2 with Suhosin-Patch (cli) (built: Oct 13 2011 23:09:42)
Copyright (c) 1997-2011 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2011 Zend Technologies
with XCache v1.3.2, Copyright (c) 2005-2011, by mOo
with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans
with Suhosin v0.9.32.1, Copyright (c) 2007-2010, by SektionEins GmbH

$ redis-cli info
redis_version:2.2.2

@starjiang
@vavr

Its realy strange, because that the documentation was written following items:

connect, open

Description
Connects to a Redis instance.

Parameters
host: string. can be a host, or the path to a unix domain socket
port: int, optional
timeout: float, value in seconds (optional, default is 0 meaning unlimited)

This issue exactly about this problem! Your solution is quite good, and we use it now in our code, but this behavior is different from documentation and i think it is a bug :)

@nicolasff
Owner
@vavr

I called this script from console (PHP_SAPI === 'cli')

set_time_limit(0);
var_dump(ini_get('max_input_time'));
$ string(2) "-1"
var_dump(ini_get('max_execution_time'));
$ string(1) "0"

So the question is still actual!

@nicolasff
Owner
@vavr

I've never heard of such a parameter :)

ini_set('default_socket_timeout', -1);// it works fine

Thank you very much for your help, now everything works as expected

@salimane

is it possible in order to take of the default_time_socket problem to add a parameter to connect, pconnect...to reconnect if can't connect to avoid some try {} catch {}
Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.