-
Notifications
You must be signed in to change notification settings - Fork 931
Confusion Regarding ASAN #1043
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! Does this also happen in Debug mode or only in Release builds? |
Thank you for your reply. Through testing, I've observed that this behavior occurs in static libraries compiled under both "Debug" and "RelWithDebInfo" configurations. |
@daanx @Niteip
The above is my naive understanding. I don't know if this is the real reason that leads to the imprecise asan of mimalloc in this issue. Maybe we just need to mark UNPOISON for the specific data instead of the padding bytes and mi_padding_t struct? Looking forward to your reply! |
Thank you for your reply. I think what you said makes a lot of sense. Moreover, I conducted a test where I specifically modified the code (in types.h), changing After compiling it into a static library, my test code was successfully detected as "poisoned" by ASAN. |
Sorry, what I said before was not rigorous enough. When #define MI_PADDING 0, test code:
After multiple tests, I found that different values of count yield different results. count = 8; // ASAN reports an error as expected |
@Niteip In mimalloc, different types of pages (small, medium, large, or huge) are allocated depending on how much memory is requested. There are some differences in zero-initialization and other aspects between huge page and normal page (small, medium, large).
The problem here is that we cannot // and try again, this time succeeding! (i.e. this should never recurse through _mi_page_malloc)
void* p;
if mi_unlikely(zero && mi_page_is_huge(page)) {
// note: we cannot call _mi_page_malloc with zeroing for huge blocks; we zero it afterwards in that case.
p = _mi_page_malloc(heap, page, size);
mi_assert_internal(p != NULL);
_mi_memzero_aligned(p, mi_page_usable_block_size(page));
}
else {
p = _mi_page_malloc_zero(heap, page, size, zero);
mi_assert_internal(p != NULL);
}
// Here is the new code that marks
// the padding bytes and mi_padding_t struct as POISON
#if MI_PADDING
mi_padding_t* const padding = (mi_padding_t*)((uint8_t*)p + mi_page_usable_block_size(page));
ptrdiff_t delta = ((uint8_t*)padding - (uint8_t*)p - (size - MI_PADDING_SIZE));
uint8_t* fill = (uint8_t*)padding - delta;
const size_t maxpad = (delta > MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : delta);
mi_track_mem_noaccess(fill, maxpad + sizeof(mi_padding_t));
#endif
// move singleton pages to the full queue
if (page->reserved == page->used) {
mi_page_to_full(page, mi_page_queue_of(page));
}
return p; I did a simple test of the above code and it passed all 42 tests in I'm not particularly sure this is foolproof, it hasn't been heavily tested and could be potentially buggy. Is there a better and more elegant implementation? I look forward to your reply and any discussion on this topic. |
mark the padding bytes and mi_padding_t struct no access for all kinds of pages to improve asan accuracy(issue microsoft#1043)
Hello, I enabled the mimalloc ASAN feature and noticed a minor issue: insufficient accuracy.
For example, in code like this:
No error was triggered. However, when I tried a larger out-of-bounds access:
It finally reported an error: "use of poisoned memory."
This suggests that mimalloc ASAN's detection is not precise enough.
My development environment: Windows, Visual Studio 2022, mimalloc 2.1.7, using the mimalloc static library with MI_TRACK_ASAN=ON and MI_OVERRIDE=OFF.
I look forward to your assistance.
The text was updated successfully, but these errors were encountered: