-
Notifications
You must be signed in to change notification settings - Fork 949
Assertion if used with LLVM code base together with mimalloc-new-delete.h new/delete overwriting #245
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
Comments
Thanks for the report. The assert: alignment > 0 && alignment % sizeof(void*) == 0 indicates that the alignment is either 0 or not a multiple of a machine word -- that is generally not good and I am surprised that happens since your
so the assertion seems ok. |
I agree that you are right for the limitations that are allowed. I investigated the crash on Linux:
The alignment is 4. The type is some wrapped integer. Thought, e.g. on neither Linux, macOS nor Windows the default allocators bail out with such an issue (the aligned variants are used there, too). I would assume is is common to call the aligned variants in templates, like in this case and I think it would be a hassle to start to preach to the projects to guard them with type alignment conditions. Other malloc implementations relaxed this restraint, too, it seems, to accommodate user space code used to the more relaxed behavior of the system libc allocators, see e.g. https://bugzilla.mozilla.org/show_bug.cgi?id=526152 Could such a relaxation be possible here, too? |
The trivial patch in the linked pull request will fix the issue like e.g. done for jemalloc. |
I looked at the PR as well -- thanks so much. I think is is fixed in c9ffe30 on |
Ok, I tried this again. Many things work (like my initial unit test that failed before), but some other runs then hit the next assert later in the function. I guess the unit test is lucky and uses the early out for 'small block found'. The failing assert is the: assertion: "adjust % sizeof(uintptr_t) == 0" which makes sense, as this will not hold, if the alignment didn't have the sizeof(...) requirement. |
Ah of course. I guess we should remove that assertion as well.. |
Just pushed a fix; hope it work now. :-) |
I think that just went to dev-slice - dunno if that was intentional. :) |
I will redo my testing with the master version and adjusted asserts: mi_assert(alignment > 0); |
Hmm, actually, not even the unit tests of mimalloc pass with just these two changes:
1/2 Test #1: test_api, ........................Child aborted***Exception: 0.00 sec
2/2 Test #2: test_stress, ..................... Passed 2.24 sec |
Hmm, given the uintptr_t adjust = alignment - (((uintptr_t)p + offset) & align_mask); computation, when would adjust be ever > alignment? |
Ah, that was embarrassing -- fixed now I hope and pushed to (yes, it is a bit obvious this always holds but the philosophy of mimalloc is to always make invariants explicit and checked even if we can "obviously" derive them from the code. For an allocator i think this is the only way to get confidence in the code as unit test never cover enough cases) |
Ok, this should do the job for me, thanks for taking care! |
I compiled a program using the LLVM/clang libraries and overwrote the global new/delete/... operators via mimalloc-new-delete.h
This leads to an assert for debug builds for the aligned new variants (on both Linux & macOS)
mimalloc: assertion failed: at "/Volumes/makefactory/mimalloc-Add0B0VQ/mimalloc/src/src/alloc-aligned.c":20, mi_heap_malloc_zero_aligned_at
assertion: "alignment > 0 && alignment % sizeof(void*) == 0"
4 rules-cxx 0x0000000110480e6a _mi_assert_fail.cold.1 + 58
5 rules-cxx 0x00000001101245d2 _mi_assert_fail + 18
6 rules-cxx 0x000000011012168f mi_heap_malloc_zero_aligned_at + 79
7 rules-cxx 0x0000000110120bc2 mi_new_aligned + 34
8 rules-cxx 0x000000010ec5a269 _ZN4llvm8DenseMapIjN5clang17DiagnosticMappingENS_12DenseMapInfoIjEENS_6detail12DenseMapPairIjS2_EEE4growEj + 121
9 rules-cxx 0x000000010ec5a0ee ZN4llvm12DenseMapBaseINS_8DenseMapIjN5clang17DiagnosticMappingENS_12DenseMapInfoIjEENS_6detail12DenseMapPairIjS3_EEEEjS3_S5_S8_E20InsertIntoBucketImplIjEEPS8_RKjRKT_SC + 78
10 rules-cxx 0x000000010ec53e41 _ZN5clang17DiagnosticsEngine11setSeverityEjNS_4diag8SeverityENS_14SourceLocationE + 625
11 rules-cxx 0x000000010ec53fe2 _ZN5clang17DiagnosticsEngine19setSeverityForGroupENS_4diag6FlavorEN4llvm9StringRefENS1_8SeverityENS_14SourceLocationE + 130
12 rules-cxx 0x000000010ecc5f17 _ZN5clang21ProcessWarningOptionsERNS_17DiagnosticsEngineERKNS_17DiagnosticOptionsEb + 935
13 rules-cxx 0x000000010dbacf29 _ZN5clang16CompilerInstance17createDiagnosticsEPNS_17DiagnosticOptionsEPNS_18DiagnosticConsumerEbPKNS_14CodeGenOptionsE + 1785
14 rules-cxx 0x000000010dbac7e8 _ZN5clang16CompilerInstance17createDiagnosticsEPNS_18DiagnosticConsumerEb + 40
I assume the code that uses the aligned new has some data type that has lower alignment requirements than enforce by the assert.
e.g. the call here start with some
allocate_buffer(sizeof(BucketT) * NumBuckets, alignof(BucketT)));
call that passes the alignof result to the aligned new variants.
Is the assert overly strict?
The text was updated successfully, but these errors were encountered: