曾经研究memcached的时候发现它的状态机里有一个很隐蔽的逻辑bug很难触发就随手在issue里提了个bug,如今已经被合并到memcached主干上了git
on line 3857 if update_event() return false and the connection's bind event is still EV_READ c->state will be conn_closing and stop will be true if no more bytes comes, the socket will never be cleanup?
就是说在memcache.c的3857行若是update_event()返回false而且 链接的bind event依旧是EV_READgithub
c->state将会是conn_closing 并且 stop的值将会是truebash
这时若是没有更多的数据从socket上传入socket将永远不会被清理形成泄漏less
Status: Fixed:运维
https://code.google.com/p/memcached/issues/detail?id=261&can=1&q=auxtenwpc%40gmail.comsocket
https://github.com/memcached/memcached/commit/b2734f8321230bd52e36df7f82a6b1d71532e496ide
过了两年才有人鸟我而后被合并到主干上了:-)memcached
Reported by auxten...@gmail.com, Mar 17, 2012google
3839 case conn_new_cmd: 3840 /* Only process nreqs at a time to avoid starving other 3841 connections */ 3842 3843 --nreqs; 3844 if (nreqs >= 0) { 3845 reset_cmd_handler(c); 3846 } else { 3847 pthread_mutex_lock(&c->thread->stats.mutex); 3848 c->thread->stats.conn_yields++; 3849 pthread_mutex_unlock(&c->thread->stats.mutex); 3850 if (c->rbytes > 0) { 3851 /* We have already read in data into the input buffer, 3852 so libevent will most likely not signal read events 3853 on the socket (unless more data is available. As a 3854 hack we should just put in a request to write data, 3855 because that should be possible ;-) 3856 */ 3857 if (!update_event(c, EV_WRITE | EV_PERSIST)) { 3858 if (settings.verbose > 0) 3859 fprintf(stderr, "Couldn't update event\n"); 3860 conn_set_state(c, conn_closing); 3861 } 3862 } 3863 stop = true; 3864 } 3865 break; on line 3857 if update_event() return false and the connection's bind event is still EV_READ c->state will be conn_closing and stop will be true if no more bytes comes, the socket will never be cleanup? so i think there need a patch --- a/memcached.c +++ b/memcached.c @@ -3858,6 +3858,7 @@ static void drive_machine(conn *c) { if (settings.verbose > 0) fprintf(stderr, "Couldn't update event\n"); conn_set_state(c, conn_closing); + break; } } stop = true;
Project Member #1 dorma...@rydia.netspa
Wow, two years old... and it looks correct to me. If that update_event fails the connection might zombie. It's very hard for that to fail and it's been that way forever. Pushed a commit for the next release.
欢迎加入运维开发技术分享QQ群365534424