facebook / rocksdb

A library that provides an embeddable, persistent key-value store for fast storage.
http://rocksdb.org
GNU General Public License v2.0
28.23k stars 6.26k forks source link

fix compilation check for `malloc_usable_size()` presence #6494

Open ajkr opened 4 years ago

ajkr commented 4 years ago

Note: Please use Issues only for bug reports. For questions, discussions, feature requests, etc. post to dev group: https://groups.google.com/forum/#!forum/rocksdb or https://www.facebook.com/groups/rocksdb.dev

Expected behavior

When non-default allocator is chosen (jemalloc or tcmalloc), the presence of malloc_usable_size() in that particular allocator should be used to decide the value of -DROCKSDB_MALLOC_USABLE_SIZE.

Actual behavior

Regardless of the configured allocator, the compilation checks for the presence of malloc_usable_size() in the default allocator: https://github.com/facebook/rocksdb/blob/0a0151fb99b306dc0b1f6b22df8073f8084da795/build_tools/build_detect_platform#L412-L425. This causes runtime crashes when the default allocator supports malloc_usable_size() but the runtime allocator does not (e.g., older versions of tcmalloc).

Phantomape commented 4 years ago

Trying to reproduce it with Centos6 and tcmalloc 1.5(malloc_usable_size is only available after 1.6), somehow the code compiles and runs well. I wonder what went wrong in my situation. May I ask under what circumstances did you reproduce such an error?

ajkr commented 4 years ago

Hm, IIRC that is the same setup where I first encountered the problem. Tried reproing it again and still saw it.

$ make clean && ROCKSDB_NO_FBCODE=1 ROCKSDB_DISABLE_JEMALLOC=1 make -j48 db_bench
...
$ ./db_bench -benchmarks=fillrandom -write_buffer_size=1048576 -compression_type=none
...
Received signal 11 (Segmentation fault)
#0   /lib64/libc.so.6(malloc_usable_size+0x26) [0x7f5490e0fe56] ??      ??:0
#1   ./db_bench() [0x643aa4] rocksdb::Arena::AllocateNewBlock(unsigned long)    /home/andrewkr/local/rocksdb/memory/arena.cc:215
#2   ./db_bench() [0x643be7] rocksdb::Arena::AllocateFallback(unsigned long, bool)      /home/andrewkr/local/rocksdb/memory/arena.cc:108
#3   ./db_bench() [0x643d80] rocksdb::Arena::AllocateAligned(unsigned long, unsigned long, rocksdb::Logger*)    /home/andrewkr/local/rocksdb/memory/arena.cc:195
#4   ./db_bench() [0x5822cc] std::__atomic_base<unsigned long>::store(unsigned long, std::memory_order) /usr/include/c++/4.8.2/bits/atomic_base.h:474
#5   ./db_bench() [0x5826c7] rocksdb::ConcurrentArena::AllocateAligned(unsigned long, unsigned long, rocksdb::Logger*)  /home/andrewkr/local/rocksdb/./memory/concurrent_arena.h:64
#6   ./db_bench() [0x6472e7] rocksdb::InlineSkipList<rocksdb::MemTableRep::KeyComparator const&>::AllocateNode(unsigned long, int)      /home/andrewkr/local/rocksdb/./memtable/inlineskiplist.h:628
#7   ./db_bench() [0x64794d] rocksdb::(anonymous namespace)::SkipListRep::Allocate(unsigned long, char**)       /home/andrewkr/local/rocksdb/memtable/skiplistrep.cc:31
#8   ./db_bench() [0x57e21c] rocksdb::MemTable::Add(unsigned long, rocksdb::ValueType, rocksdb::Slice const&, rocksdb::Slice const&, bool, rocksdb::MemTablePostProcessInfo*, void**)   /home/andrewkr/local/rocksdb/db/memtable.cc:491
#9   ./db_bench() [0x5f5977] rocksdb::MemTableInserter::PutCFImpl(unsigned int, rocksdb::Slice const&, rocksdb::Slice const&, rocksdb::ValueType)       /home/andrewkr/local/rocksdb/db/write_batch.cc:1432
#10  ./db_bench() [0x5f6347] rocksdb::MemTableInserter::PutCF(unsigned int, rocksdb::Slice const&, rocksdb::Slice const&)       /home/andrewkr/local/rocksdb/db/write_batch.cc:1506
#11  ./db_bench() [0x5ed500] rocksdb::Status::operator=(rocksdb::Status&&)      /home/andrewkr/local/rocksdb/./include/rocksdb/status.h:367
#12  ./db_bench() [0x5eda74] rocksdb::WriteBatch::Iterate(rocksdb::WriteBatch::Handler*) const  /home/andrewkr/local/rocksdb/db/write_batch.cc:521
#13  ./db_bench() [0x5f08eb] rocksdb::WriteBatchInternal::InsertInto(rocksdb::WriteThread::WriteGroup&, unsigned long, rocksdb::ColumnFamilyMemTables*, rocksdb::FlushScheduler*, rocksdb::TrimHistoryScheduler*, bool, unsigned long, rocksdb::DB*, bool, bool, bool)        /home/andrewkr/local/rocksdb/db/write_batch.cc:1990 (discriminator 1)
#14  ./db_bench() [0x542d31] rocksdb::Status::operator=(rocksdb::Status&&)      /home/andrewkr/local/rocksdb/./include/rocksdb/status.h:365
#15  ./db_bench() [0x54595d] rocksdb::DBImpl::WriteImpl(rocksdb::WriteOptions const&, rocksdb::WriteBatch*, rocksdb::WriteCallback*, unsigned long*, unsigned long, bool, unsigned long*, unsigned long, rocksdb::PreReleaseCallback*)  /home/andrewkr/local/rocksdb/db/db_impl/db_impl_write.cc:151
#16  ./db_bench() [0x546cf2] rocksdb::DBImpl::Write(rocksdb::WriteOptions const&, rocksdb::WriteBatch*) /home/andrewkr/local/rocksdb/db/db_impl/db_impl_write.cc:53
#17  ./db_bench() [0x469bd6] rocksdb::Benchmark::DoWrite(rocksdb::ThreadState*, rocksdb::Benchmark::WriteMode)  /home/andrewkr/local/rocksdb/tools/db_bench_tool.cc:4491 (discriminator 1)
#18  ./db_bench() [0x44ebf2] rocksdb::Stats::Stop()     /home/andrewkr/local/rocksdb/tools/db_bench_tool.cc:1909 (discriminator 3)
#19  ./db_bench() [0x60d962] rocksdb::(anonymous namespace)::StartThreadWrapper(void*)  /home/andrewkr/local/rocksdb/env/env_posix.cc:454
#20  /lib64/libpthread.so.0(+0x7dd5) [0x7f54926d7dd5] ??        ??:0
#21  /lib64/libc.so.6(clone+0x6d) [0x7f5490e87ead] ??   ??:0
Segmentation fault (core dumped)

Are you using make or cmake? cmake should not have a problem. If you're using make do you mind building a binary (e.g., db_bench) and then reporting the output of these commands?

$ grep DROCKSDB_MALLOC_USABLE_SIZE ./make_config.mk
$ ldd ./db_bench  | grep tcmalloc
$ nm -D <path to your libtcmalloc.so> | grep malloc_usable_size
Phantomape commented 4 years ago

Hmmm, I'm using make and I can repro the problem from the db_bench case you provided. The code that works fine is the one used in the build_detect_platform script `

include int main() {

size_t res = malloc_usable_size(0);
(void)res;
return 0; }
`