Problem/Motivation
I just update to the latest redis code which uses the new EVAL functionality. Unfortunately after the update the whole site was broken.
All I got was: Segmentation fault (core dumped)
So I debugged the core with gdb:
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Core was generated by `/usr/bin/php -d magic_quotes_gpc=Off -d magic_quotes_runtime=Off -d magic_quote'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 _zend_mm_free_int (heap=0x2c7bf90, p=0x7f38cb620058) at /build/php5-RvVZKb/php5-5.6.10+dfsg/Zend/zend_alloc.c:2104
2104 /build/php5-RvVZKb/php5-5.6.10+dfsg/Zend/zend_alloc.c: No such file or directory.
This didn't say to much, but executing where
delivered this backtrace:
#0 _zend_mm_free_int (heap=0x2c7bf90, p=0x7f38cb620058) at /build/php5-RvVZKb/php5-5.6.10+dfsg/Zend/zend_alloc.c:2104
#1 0x00007f38be799b33 in zim_Redis_hMset () from /usr/lib/php5/20131226/redis.so
#2 0x00000000006cb35b in dtrace_execute_internal (execute_data_ptr=<optimized out>, fci=<optimized out>, return_value_used=<optimized out>) at /build/php5-RvVZKb/php5-5.6.10+dfsg/Zend/zend_dtrace.c:97
#3 0x0000000000781328 in zend_do_fcall_common_helper_SPEC (execute_data=<optimized out>) at /build/php5-RvVZKb/php5-5.6.10+dfsg/Zend/zend_vm_execute.h:560
#4 0x0000000000716838 in execute_ex (execute_data=0x7f38cb728050) at /build/php5-RvVZKb/php5-5.6.10+dfsg/Zend/zend_vm_execute.h:363
....
So it was clearly related to redis, exactly to redis and the command hMset()
.
Only thing that changed there was the new volatile
flag.
Fiddling with this showed that everything worked fine without the volatile
item in the array.
Further investigation showed that the volatile
value in the $hash
was a boolean, which was suspect because there's a type cast (int)
but it seems only to cast CACHE_TEMPORARY
, which is a constant and an integer anyway...
Wrapping the comparison in parenthesis and casting the returned bool to int worked then.
All this is not nice but it's not this modules fault that this leads to a segfault (the php extension should take care of such things), so I checked the issue queue of phpredis and there are hints that this I indeed a problem but maybe is just the case for php 5.6 & phpredis < 2.2.7:
- Cause core-dump when using hMset() and attributes including null (php5.6 + fpm)
- phpredis segfaults for NULL values on PHP 5.6.2 (worked on 5.5)
Proposed resolution
Wrap the comparison to set the volatile
flag in Redis_Cache_Predis::set()
/ Redis_Cache_PhpRedis::set()
in parenthesis. That way we keep the module phpredis version independent.
Remaining tasks
Reviews needed.
User interface changes
None.
API changes
None.
Data model changes
None.
Comment | File | Size | Author |
---|---|---|---|
redis-avoid-segfault-by-propery-type-casting.patch | 974 bytes | das-peter |
Comments
Comment #1
pounardWow very nice catch, It seems to be a very bad bug of php-redis, but since a lot of people will probably use wrong versions, and because the fix that seems to resolve everything on your box is trivial and makes an ambiguous code line more strict, I'll trust you the eyes closed about this one and just merge the patch.
I'll do it within the day, thanks again.
Comment #3
pounardCommited and pushed a new release.
I will now try to see if this will happen in 3.x too.
Comment #4
pounardOk, the 3.x should not be impacted, thank you very much once again.