uint32_t overflow cause busy loop in 1.0.18
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
libmemcached |
New
|
Undecided
|
Unassigned |
Bug Description
We are using libmemcached 1.0.18 and observed occasionally very high CPU consumption.
After some debugging, the cause is located in libmemcached/
bool memcached_
{
.............
uint32_t no_msg= memcached_
for (uint32_t x= 0; x < no_msg; x++) // busy loop here
{
.....
}
}
During debugging, we found that memcached_
In order to fix this issue, we took an quick & dirty solution, which refuses to decrement by 1 when 0. This patch is attached below.
But still, I haven't found the root cause, and I'm afraid the root cause would leads to more possible hidden issues. So hope someone else could catch and fix this bug.
memcached_ server_ response_ count(ptr) returns 0 when ptr is NULL or ptr->cursor_active is NULL. Decrementing this and assigning to a uint32_t produces 2^32-1, so the error check if (no_msg > 0) only fails if ptr->cursor_active == 1. I suspect the right answer is to not use uint32_t here (before it was uint32_t it was int; not sure why it was converted to unsigned) and instead use int32_t. That change is here:
http:// bazaar. launchpad. net/~tangent- trunk/libmemcac hed/1.2/ revision/ 509/libmemcache d/memcached_ purge.c
For what it's worth, I've seen this bug tickled when calling set with a key containing a newline (\n) from PHP 5.5's Memcached class. The Memcached server doesn't like that (seems to be interpreting the second line as a new command) and errors out -- eventually triggering this loop as it attempts to unwind from the error.