microsoft / mimalloc

mimalloc is a compact general purpose allocator with excellent performance.
MIT License
9.78k stars 800 forks source link

Clarification of MI_OVERRIDE and mimalloc-new-delete.h #535

Open thehans opened 2 years ago

thehans commented 2 years ago

Does MI_OVERRIDE=ON cmake option imply that new/delete are overridden in addition to the C malloc/etc interface?

If I compile with MI_OVERRIDE on Linux, I get "multiple definition" linker errors when I try to #include <mimalloc-new-delete.h>

Here are the messages from gcc-10:

/usr/bin/ld: submodules/mimalloc/libmimalloc-debug.a(alloc.c.o): in function `operator new(unsigned long, std::nothrow_t const&)':
/home/hans/openscad_malloc/submodules/mimalloc/src/alloc-override.c:190: multiple definition of `operator new(unsigned long, std::nothrow_t const&)'; CMakeFiles/OpenSCAD.dir/src/openscad.cc.o:/home/hans/openscad_malloc/submodules/mimalloc/include/mimalloc-new-delete.h:31: first defined here
/usr/bin/ld: submodules/mimalloc/libmimalloc-debug.a(alloc.c.o): in function `operator new[](unsigned long, std::nothrow_t const&)':
/home/hans/openscad_malloc/submodules/mimalloc/src/alloc-override.c:191: multiple definition of `operator new[](unsigned long, std::nothrow_t const&)'; CMakeFiles/OpenSCAD.dir/src/openscad.cc.o:/home/hans/openscad_malloc/submodules/mimalloc/include/mimalloc-new-delete.h:32: first defined here
/usr/bin/ld: submodules/mimalloc/libmimalloc-debug.a(alloc.c.o): in function `mi_free':
/home/hans/openscad_malloc/submodules/mimalloc/src/alloc.c:481: multiple definition of `operator delete[](void*)'; CMakeFiles/OpenSCAD.dir/src/openscad.cc.o:/home/hans/openscad_malloc/submodules/mimalloc/include/mimalloc-new-delete.h:26: first defined here
/usr/bin/ld: submodules/mimalloc/libmimalloc-debug.a(alloc.c.o): in function `mi_free':
/home/hans/openscad_malloc/submodules/mimalloc/src/alloc.c:481: multiple definition of `operator delete(void*)'; CMakeFiles/OpenSCAD.dir/src/openscad.cc.o:/home/hans/openscad_malloc/submodules/mimalloc/include/mimalloc-new-delete.h:25: first defined here
/usr/bin/ld: submodules/mimalloc/libmimalloc-debug.a(alloc.c.o): in function `mi_free_size':
/home/hans/openscad_malloc/submodules/mimalloc/src/alloc.c:576: multiple definition of `operator delete[](void*, unsigned long)'; CMakeFiles/OpenSCAD.dir/src/openscad.cc.o:/home/hans/openscad_malloc/submodules/mimalloc/include/mimalloc-new-delete.h:36: first defined here
/usr/bin/ld: submodules/mimalloc/libmimalloc-debug.a(alloc.c.o): in function `mi_free_size':
/home/hans/openscad_malloc/submodules/mimalloc/src/alloc.c:576: multiple definition of `operator delete(void*, unsigned long)'; CMakeFiles/OpenSCAD.dir/src/openscad.cc.o:/home/hans/openscad_malloc/submodules/mimalloc/include/mimalloc-new-delete.h:35: first defined here
/usr/bin/ld: submodules/mimalloc/libmimalloc-debug.a(alloc.c.o): in function `mi_new':
/home/hans/openscad_malloc/submodules/mimalloc/src/alloc.c:857: multiple definition of `operator new[](unsigned long)'; CMakeFiles/OpenSCAD.dir/src/openscad.cc.o:/home/hans/openscad_malloc/submodules/mimalloc/include/mimalloc-new-delete.h:29: first defined here
/usr/bin/ld: submodules/mimalloc/libmimalloc-debug.a(alloc.c.o): in function `mi_new':
/home/hans/openscad_malloc/submodules/mimalloc/src/alloc.c:857: multiple definition of `operator new(unsigned long)'; CMakeFiles/OpenSCAD.dir/src/openscad.cc.o:/home/hans/openscad_malloc/submodules/mimalloc/include/mimalloc-new-delete.h:28: first defined here

(I got even stranger messages if I tried to build with clang-14, where it claimed they were redefined in boost/system/detail/std_interoperability.hpp which I assume was some kind of compiler bug since I saw no such definitions in that file)

Is the answer specific to target OS? (i.e. MI_OVERRIDE implies new/delete override, everywhere EXCEPT on Windows?) I'm wondering about this since MI_OVERRIDE defaults ON, and I see this preprocessor conditional in the tests: https://github.com/microsoft/mimalloc/blob/38a03229c89afbf2722e48c63da696bf11589dee/test/main-override.cpp#L17-L19

daanx commented 2 years ago

Thanks @thehans for all your feedback!

I can see it is a bit confusing and will try to improve the documentation; However, it is partly confusing because there is inherent complexity in many ways to override malloc: use #defines (mimalloc-override.h), use static linking override (mimalloc-override.o), use dynamic override (e.g. LD_PRELOAD), use from C or C++, and the various ways the different OS's and linkers work. It would be great if there is was one standard way to do things but there just isn't and the right way depends the application.

Having said that:

As you can see, a lot of this is beyond the scope of mimalloc but more about linking C/C++ on various platforms. I will try if I can make this more clear with a nice diagram or something. The current goal is at least to make everything work out-of-the-box on the various platforms without needing special make flags etc.

yhyu13 commented 5 months ago

https://github.com/microsoft/mimalloc/issues/559#issuecomment-1916408486