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

Reply via email to