google / google/leveldb

Reference to tcmalloc in leveldb's shared object causes crashes upon late loading leveldb

Open
#634 1 comment 6 reactions 0 assignees View on GitHub
bug
Dominant language
C++
Stars
39.4k
Forks
8.2k
PR merge metrics
No merged PRs in 30d

Description

When dynamically loading leveldb's shared object, libtcmalloc (if enabled) is implicitly loaded too.
The loading of libtcmalloc overrides `malloc`, `free` and other libc functions.
This override is fine when it happens at the beginning of execution but causes 2 problems when it is late loaded (with `dlopen` after executable had started):
* Memory previously allocated with malloc can be freed with tcmalloc, causing a crash
* tcmalloc itself calls library code that may have already resolved its new/delete symbols to libc's whereas *direct* calls to new/delete in tcmalloc are always resolved to its own implementation.

To illustrate, compile&run this C++ program (fix the path to libleveldb)
```c++
#include
#include
int main() {
std::string s; // This fixes libstdc++ new/delete to use malloc/free. No crash without it!
dlopen("/usr/lib/x86_64-linux-gnu/libleveldb.so", RTLD_NOW); // directly loading tcmalloc causes the same problem
return 0;
}
```

This bug had been hit many times, looks like:
```
[src/tcmalloc.cc:283] Attempt to free invalid pointer 0x562806a73fb0
```

https://github.com/commercialhaskell/stack/issues/2926

https://stackoverflow.com/questions/50132801/debugging-a-failure-to-access-libleveldb-with-c-sharp-on-osx

https://github.com/junyanz/interactive-deep-colorization/issues/26

https://github.com/lamdu/lamdu/issues/104#issuecomment-435697410

I suggest removing `tcmalloc` references in `leveldb`. Document that it is recommended for use in the user application, instead. This will allow safe late-loading of leveldb.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.