gperftools: dynamically loading libtcmalloc is unsafe (was: Dynamic linking with tcmalloc is prone to crash)
libtcmalloc, designed to override weak symbols (malloc/free), can crash when late-loaded dynamically (with dl_open
).
Consider the code in MallocExtension::Initialize
:
string dummy("I need to be allocated");
dummy += "!"; // so the definition of dummy isn't optimized out
It calls into libstdc++'s basic_string
allocation methods, which may have already been resolved to use libc’s malloc (if C++ strings were in use prior to the dl_open). Then the dtor/free calls the delete[]
symbol directly and not via basic_string
(probably due to inlining), which is newly loaded code, so is resolved to use tc_free
.
This crashes with:
src/tcmalloc.cc:283] Attempt to free invalid pointer 0x55ef8c535fb0
Using dl_open
on ANY shared object which indirectly loads libtcmalloc
- after instantiating std::string
- will cause this crash.
In other words, the only safe use of libtcmalloc
is via -l tcmalloc
in the MAIN application, or via LD_PRELOAD
. It is not safe to use libtcmalloc
via -l tcmalloc
in library code. That makes the library code dangerous to late-load.
Since late loading is a crucial technique for various programming languages (e.g: Python, Julia, Haskell in interpreted mode, …), crashing upon late load of tcmalloc is a problem.
I don’t know if there’s a good fix for this, except emphasizing in the documentation that -l tcmalloc
is only supported in the main, and will cause this terrible bug otherwise.
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 8
- Comments: 21 (12 by maintainers)
I have a very similar crash when trying to run a golang application that is linked to a dynamic c++ library, itself linked with -ltcmalloc:
This is on Ubuntu 18. golang 1.11.2
I can make the crash go away if I explicitly link the go application against tcmalloc (add a -ltcmalloc somewhere in the
cgo
build process).