the commit
d406f228 in gperf implements a c11 feature used by a
recent change in rocksdb:
16e03882, which uses aligned_alloc().
and
16e03882 in rocksdb was merged after v5.7 was tagged, while
16e03882 in gperf was merged after v2.6.1 was tagged.
because aligned_alloc() is not implemented by tcmalloc until the
not-yet-released 2.6.2, if we call aligned_alloc() in an application
linked against tcmalloc, what gets called will be the glibc's
aligned_alloc(). but if we free() the memory chunk allocated by
aligned_alloc(), the tcmalloc's implementation kicks in, then
InvalidFree() is called, because the memory chunk being freed was
allocated by tcmalloc. in short, "mixing allocators", quote from
Dan Mick.
in rocksdb, aligned_alloc() is used if _ISOC11_SOURCE is defined, this
makes sense, because aligned_alloc() is a C11 function. we could avoid
using it by not defining _ISOC11_SOURCE. but as long as _GNU_SOURCE is
defined, glibc defines _ISOC11_SOURCE. and libstdc++ requires
_GNU_SOURCE, because it uses a fair amount of GNU extensions.
Fixes: http://tracker.ceph.com/issues/21422
Signed-off-by: Kefu Chai <kchai@redhat.com>
endforeach()
set(ROCKSDB_VERSION_STRING
"${ROCKSDB_VERSION_MAJOR}.${ROCKSDB_VERSION_MINOR}.${ROCKSDB_VERSION_PATCH}")
+
+ if(ALLOCATOR MATCHES "tcmalloc(_minimal)?")
+ # see http://tracker.ceph.com/issues/21422
+ if(ROCKSDB_VERSION_STRING VERSION_GREATER 5.7 AND
+ TCMALLOC_VERSION_STRING VERSION_GREATER 2.5 AND
+ TCMALLOC_VERSION_STRING VERSION_LESS 2.6.2)
+ message(SEND_ERROR
+ "Incompatible tcmalloc v${TCMALLOC_VERSION_STRING} and rocksdb v${ROCKSDB_VERSION_STRING}, "
+ "please install gperf-tools 2.5 or > 2.6.2")
+ endif()
+ endif()
endmacro()