On Tue, 6 Feb 2018, Paul Smith wrote:
My environment has been using GCC 6.2 (locally compiled) on GNU/Linux systems. We use a separate heap management library (jemalloc) rather than the libc allocator. The way we did this in the past was to declare operator new/delete (all forms) as inline functions in a header
Are you sure you still have all forms? The aligned versions were added in gcc-7 IIRC.
and ensure that this header was always the very first thing in every source file, before even any standard header files. I know that inline operator new/delete isn't OK in the C++ standard, but in fact it has worked for us on the systems we care about.
Inline usually works, but violating the ODR is harder... I would at least use the always_inline attribute to improve chances (I assume that static (or anonymous namespace) versions wouldn't work), since the optimizer may decide not to inline otherwise. Something based on visibility should be somewhat safer. But it still seems dangerous, some global libstdc++ object might be initialized using one allocator then used with another one...
I'm attempting a toolchain upgrade which is switching to GCC 7.3 / binutils 2.30 (along with many other updates). Now when I run our code, I get a core on exit. It appears an STL container delete is invoking libc free() with a pointer to memory allocated by jemalloc.
An example would help the discussion.
My question is, what do I need to do to ensure this behavior persists if I create a global operator new/delete? Is it sufficient to ensure that the symbol for our shared library global new/delete symbols are hidden and not global, using a linker map or -fvisibility=hidden?
I think so (hidden implies not-interposable, so locally bound), but I don't have much experience there.
-- Marc Glisse