perl client crash after timeout while connecting

Matthieu PATOU mp at oxado.com
Thu Jun 28 17:17:43 UTC 2007


Dear list
the current version (1.23 from SVN) of the memcached perl client crash when it once fail to connect an host and the
success to connect to another host.

On my workstation (Linux ubuntu 6.10), when the problem occurs i get :

mat at hades:~/work/memcached-ref/api/perl$ perl mctest.pl
using parser: Cache::Memcached::GetParser
*** glibc detected *** perl: munmap_chunk(): invalid pointer: 0x081fd690 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(__libc_free+0x18a)[0xb7e02b4a]
perl(Perl_sv_setsv_flags+0x5cb)[0x80d370f]
perl(Perl_pp_sassign+0x56)[0x80c37e4]
perl(Perl_runops_standard+0x13)[0x80bb273]
perl(perl_run+0x2e1)[0x80639b4]
perl(main+0x112)[0x8060012]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xdc)[0xb7db18cc]
perl[0x805fe81]
======= Memory map: ========


The GetParserXS module is NOT installed
After some sessions of debugging it appears that it is Perl which fools itself when executing :
   $sock = $buck2sock[$bucket] ||= $self->sock_to_host($self->{buckets}[ $bucket ]

When sock_to_host had returned undef (because it had been unable to connect to the desired server), the next execution
of this line will crash when trying to set the return value of sock_to_host into $buck2sock[$bucket]

The test case is in the mctest.pl (I simulate the timeout on connect by NOT having a memcache server listening on 11212).

I fix the bug by simplifying the code and splitting into smaller pieces (see the patch attached to this mail).

Cheers
Matthieu


-------------- next part --------------
A non-text attachment was scrubbed...
Name: mctest.pl
Type: text/x-perl
Size: 243 bytes
Desc: not available
Url : http://lists.danga.com/pipermail/memcached/attachments/20070628/380dbb02/mctest.pl
-------------- next part --------------
--- lib/Cache/Memcached.pm	2007-06-27 09:49:29.544348857 +0200
+++ Cache/Memcached.pm	2007-06-27 10:43:34.565272061 +0200
@@ -567,8 +567,11 @@
             my $tries;
             while (1) {
                 my $bucket = $hv % $bcount;
-                $sock = $buck2sock[$bucket] ||= $self->sock_to_host($self->{buckets}[ $bucket ])
-                    and last;
+                $sock = $buck2sock[$bucket] || $self->sock_to_host($self->{buckets}[ $bucket ]);
+		if ($sock) {
+			$buck2sock[$bucket] = $sock;
+			last;
+		}
                 next KEY if $tries++ >= 20;
                 $hv += _hashfunc($tries . $real_key);
             }



More information about the memcached mailing list