Monday, March 29, 2010

关于Libmemcached 编译

上一篇相关的,/2010/02/libmemcached-undefined-reference-to.html
这个是在CentOS 5.4上的编译。

但是这次是在 CentOS 4.6 上。GCC 版本 3.4.6。用上篇提供的方法,依旧是错。
这里测试了 0.37 和 0.38 两个版本。
编译参数如下:
./configure  --with-libevent-prefix=/usr/local/libevent --with-memcached --disable-64bit CFLAGS="-O3 -march=i686"


CCLD   clients/memslap
clients/ms_conn.o(.text+0x24b): In function `ms_conn_close':
clients/ms_conn.c:685: undefined reference to `__sync_fetch_and_sub'
clients/ms_conn.o(.text+0xc8e): In function `ms_setup_conn':
clients/ms_conn.c:380: undefined reference to `__sync_fetch_and_add'
clients/ms_conn.o(.text+0x11af): In function `ms_reconn_socks':
clients/ms_conn.c:1051: undefined reference to `__sync_fetch_and_add'
clients/ms_conn.o(.text+0x1351): In function `ms_verify_value':
clients/ms_conn.c:1808: undefined reference to `__sync_fetch_and_add'
clients/ms_conn.o(.text+0x13f8):clients/ms_conn.c:1767: undefined reference to `__sync_fetch_and_add'
clients/ms_conn.o(.text+0x17f4): In function `ms_build_udp_headers':
clients/ms_conn.c:194: undefined reference to `__sync_fetch_and_add'
clients/ms_conn.o(.text+0x1d46):clients/ms_conn.c:919: more undefined references to `__sync_fetch_and_add' follow
collect2: ld returned 1 exit status
make[2]: *** [clients/memslap] Error 1
make[2]: Leaving directory `/data2/space/libmemcached-0.38'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/data2/space/libmemcached-0.38'
make: *** [all] Error 2


和上次的错误略有不同。但是出错都是在 memslap 这个文件的编译上。
往上翻了翻,看到,所有的Warnings和Errors都是在 clients 下的文件编译上,而libmemcached 和 libhashkit 没问题。

于是,解决方案自然是把 clients 下所有的应用程序的编译干掉。
一开始直接去改configure出来的Makefile,太费劲了。于是只得去改 Makefile.am 然后去 automake 重新生产 Makefile.in
但是 CentOS 4.6 和 5.4 的两个系统的 autoconf 都是 2.59 的版本,改过的 Makefile.am
autoconf
aclocal.m4:20: warning: this file was generated for autoconf 2.63.
You have another version of autoconf.  It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically `autoreconf'.
configure.ac:16: error: Autoconf version 2.62 or higher is required
aclocal.m4:530: AM_INIT_AUTOMAKE is expanded from...
m4/pandora_canonical.m4:246: PANDORA_CANONICAL_TARGET is expanded from...
configure.ac:16: the top level
autom4te: /usr/bin/m4 failed with exit status: 63


换到一台 Ubuntu Lucid Lynx 的机器上,autoconf 2.69, 修改 Makefile.am,注释掉了
include clients/include.am
include tests/include.am
include example/include.am
include support/include.am


重新 aclocal; autoreconf; automake .
打包扔到开发机上,编译顺利完成。


另外,下午验证了,libmemcached 0.38 + pecl memcached 1.0.1 在 CentOS 4.6上也出现了连接无法结束的情况/2010/03/tests-about-using-tokyotyrant-with-pecl.html

Tests about using tokyotyrant with pecl memcached.

CentOS: 5.4
PHP: 5.2.13
Apache: 2.2.14
TokyoTyrant: 1.1.39

libmemcached pecl memcached result
0.37 1.0.0 works perfectly.

0.37 1.0.1 works perfectly on cli mode
zend_mm_heap corrupted in apache log(non-debug php compilation)
apache SegFaults (php --enable-debug)

0.37 1.0.2(?) works perfect.
======================================================================

0.38 1.0.0 Cannot disconnect after script execution

0.38 1.0.1 Cannot disconnect after script execution

0.38 1.0.2(?) Cannot disconnect after script execution


1.0.2(?) is the github version from http://github.com/tricky/php-memcached by Teddy(commit 078544ae226313dbdf56775bc004136c7e6b6e28).

Friday, March 12, 2010

php 处理 <? 的错误。

刚才 @iammutex 同学写 prepare 方法的时候,把一个数组dump出来,结果发现var_dump输出被截断。
大致是 array('uid=?', 'fid<?'); 的

写了个测试代码
<?php
$array = array('1', '2', '3<? 1+1', '4>111?');
var_dump($array);


猜猜输出是啥

cli 模式下:

0> /data4/space/bin/php test.php
array(4) {
[0]=>
string(1) "1"
[1]=>
string(1) "2"
[2]=>
string(7) "3<? 1+1"
[3]=>
string(6) "4>111?"
}


嗯,没有问题。

但是。。。 Apache + php ...

array(4) {
[0]=>
string(1) "1"
[1]=>
string(1) "2"
[2]=>
string(7) "3111?"
}



LOL ...

PS: 测试环境 php5.3.1 + apache 2.2.14
看到这个的人来验证一下其他的版本或者其他的httpd吧。

pecl memcached 处理默认参数就是一悲剧

这错误也怪我,之前在这个扩展的不同的地方栽了一下,后来还没注意。
代码贴在了 pastebin.com 。。。 可怜的 pastebin.ca,也在墙外了。。。

虽然贴了代码,还是有必要简要提一下,要不然哪天pastebin.com也在墙外了。
<?php
class spdLibMemcached {
private $mc;
public function __construct($persistent_id=null) {
$this->mc = new Memcached($persistent_id);
}
public function addServer($host, $port, $weight=null) {
return $this->mc->addServer($host, $port, $weight);
}
public function getServerList() {
return $this->mc->getServerList();
}
}


$a = new memcached;
$b = new memcached;
$a->addServer('10.1.0.55', 22201);
$b->addServer('10.1.3.52', 11211);

$c = new spdlibmemcached;
$d = new spdlibmemcached;
$c->addServer('10.1.0.55', 22201);
$d->addServer('10.1.3.52', 11211);

var_dump(
$a->getServerList(),
$b->getServerList(),
$c->getServerList(),
$d->getServerList()
);

你会发现 $c 和 $d 取得的结果是 。。。 两个值。。。。

刚才还去麻烦小天天看代码,也是没看出问题。

最后索性继续精简代码,写了个最简单的例子,居然是好的。一细看:
new Memcached; 和 new Memcached(null);
根本不是一回事。。。

于是构造的时候必须

<?php
class spdLibMemcached {
private $mc;
public function __construct($persistent_id=null) {
if ($persistent_id === null) {
$this->mc = new Memcached;
} else {
$this->mc = new Memcached($persistent_id);
}
}
}



继续改其他的去。。。