-
Notifications
You must be signed in to change notification settings - Fork 856
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mimalloc override + valgrind #251
Comments
I just tried to modify alloc-override.c and define the redirection as an extra call. #4 |
I'm interested too in making valgrind and mimalloc work together. [18:01:40] : [Step 2/2] -- Valgrind Check: cpp-tests ... ==13792== Memcheck, a memory error detector Relevant source code is probably this one: But we are not sure how to interpret the diagnostic message: Address ... is 0 bytes inside data symbol "_mi_heap_main" |
For me, this is taking the form of mimalloc (as a debug build) raising an assert whilst under valgrind:
|
True, I tried again with current stable mimalloc and yes, if I run a program that overrides new/delete with the mimalloc operators inside valgrind I get faults like:
|
Hi all, apologies for not replying earlier in this thread. Valgrind (and asan) is awesome! However, these tools work by knowing about the allocator (and asan for example uses its own allocator). This kind of deep integration is needed to avoid false positives as you are seeing here. As such, I do not think that mimalloc can work "out of the box" with Valgrind (or asan) and that more work is needed to make that happen (I guess hooking into specific api calls?). For now, I recommend not using mimalloc when using Valgrind or asan, and only using mimalloc for release/debug builds. This is what the Koka compiler does for example. However, it would be great if a Valgrind/asan expert could make mimalloc work natively with those tools and I would be inclined to accept such a PR :-) |
Valgrind has a very friendly group of maintainers and its own issue tracker, I'm not sure how much they spill over to Github though. It might be worth it for a maintainer of mimalloc to open an issue on their tracker and refer back to this issue for potential guidance. |
Valgrind's Memcheck has API hooks for custom memory allocators. The API is powerful and supports even two level memory pools. Among others Postgres' custom memory allocator uses the Valgrind API. It is also quiet efficient because the API does not add dependency on external libraries or does not even use function calls. It's just a bunch of macros that inject assembly code. When a process is run under Valgrind then Memchecker is able to detect and the assembly instructions. For example the Intel asm for VALGRIND_MEMPOOL_ALLOC asm
The most important APIs are
You can find my experimental branch at https://github.com/microsoft/mimalloc/compare/dev...tiran:valgrind?expand=1 . (disclaimer: it doesn't work yet). |
More useful links:
|
Very cool @tiran; thanks for the pointers! I have also been looking into asan support which works similarly. However, I think we talked about having the goal of having valgring/asan integration in mimalloc as always enabled, but I think that will not work while maintaining good performance. (for example, mimalloc I think I have time later this month to try to take your branch and see if we can make it work. |
I agree, the valgrind code should be optional and not enabled by debug. My branch has the code behind |
jemalloc 4.5 used an additional trick to reduce the performance impact of Valgrind macros. It had a global variable that was initialized on startup. The variable was checked before every call to a Valgrind macro or helper method. Mimalloc could use the same approach in addition to
|
Very late followup -- but I just got around to adding initial valgrind support in the latest See the comments in |
Hi, thanks that you did work on this, I will give this some try. |
First feeback, the dev-slice branch failed to compile here due to our more restrictive compiler flags:
tag is unused |
Beside this, first tests look fine, if I use the --soname-synonyms='somalloc=mimalloc' switch valgrind seems to work fine on first glance with just using the mimalloc-new-delete.h for new/delete overwriting. |
Unfortunately for me some of the programs we have crash during the run of the global destructors. (I only used the mimalloc-new-delete.h to overwrite new/delete)
|
Thanks @christoph-cullmann -- I fixed the compiler warning and good to hear it seems to work for you now. I also tested myself on the benchmark suite programs and things worked as well. It took quite a while to make this work as I kept getting errors in multithreaded programs but I finally figured out I had a misunderstanding of how the model worked :-). In the test file ( @tiran : if you find time it would be great if you could test this with the Python integration. |
ah that is not good -- but this has nothing to do with valgrind I think ? It looks like a pointer is being deleted that was not allocated by mimalloc:
Try to run the program without linking to mimalloc and using (ps. ah, just in case, a work-around is to go into |
Will try LD_PRELOAD. |
Ok, issue in our code base, malloc vs. delete. Nice to have this found, valgrind didn't catch this. |
I'm using Given the fact that it immediately behaves wrongly in the calls of
It is even more problematic when using The only working one I've tried is Everything seems OK without memcheck, except that |
Hi @FrankHB, I have recently been improving valgrind and asan support, and the latest It should work well with static linking and malloc/free overriding. I have not been able to make valgrind work with LD_PRELOAD.. as I understood at the time, this is not really possible since valgrind tries to take over malloc/free itself. (which is why we need the funny command line even with static linking). |
Hi,
if you use valgrind for debugging (which is often very useful), this works ok with mimalloc and override beside that for the free's (if you use C++), you will get a lot of warnings about mismatching delete/delete[]/free usage.
Example:
==171393== Mismatched free() / delete / delete []
==171393== at 0x483A9AB: free (vg_replace_malloc.c:540)
==171393== by 0x317E26: Ur::MessageHandler::~MessageHandler() (in /home/cullmann/projects/build/libur.default.release/libur/test/test_gcallocator_exe)
==171393== by 0x2FF2FC: Ur::StaticInitializer::~StaticInitializer() (in /home/cullmann/projects/build/libur.default.release/libur/test/test_gcallocator_exe)
==171393== by 0x4A53536: __run_exit_handlers (in /usr/lib/libc-2.31.so)
==171393== by 0x4A536ED: exit (in /usr/lib/libc-2.31.so)
==171393== by 0x4A3C029: (below main) (in /usr/lib/libc-2.31.so)
==171393== Address 0x4be0420 is 0 bytes inside a block of size 64 alloc'd
==171393== at 0x483A50F: operator new[](unsigned long) (vg_replace_malloc.c:433)
==171393== by 0x3174D6: Ur::MessageHandler::MessageHandler() (in /home/cullmann/projects/build/libur.default.release/libur/test/test_gcallocator_exe)
==171393== by 0x2FF170: Ur::StaticInitializer::StaticInitializer() (in /home/cullmann/projects/build/libur.default.release/libur/test/test_gcallocator_exe)
==171393== by 0x2C4CFD: _GLOBAL__sub_I_test_gcallocator.cpp (in /home/cullmann/projects/build/libur.default.release/libur/test/test_gcallocator_exe)
==171393== by 0x48189C: __libc_csu_init (in /home/cullmann/projects/build/libur.default.release/libur/test/test_gcallocator_exe)
==171393== by 0x4A3BFAF: (below main) (in /usr/lib/libc-2.31.so)
This can be avoided, if one doesn't redirect directly but still do an extra call inside the overriding by enforcing to use the
#define MI_FORWARD1(fun,x) { return fun(x); }
variant of forwarding.
Would it be possible to have this as a cmake option? I can patch that file to always use this variant, but I assume other people will stumble over this sooner or later, too.
(or is there some more appropriate way to handle this?)
The text was updated successfully, but these errors were encountered: