-
Notifications
You must be signed in to change notification settings - Fork 7
Enforce aligned allocation on FreeBSD #36
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
Conversation
This fixes those errors experienced on FreeBSD: crunch/crnlib/crn_mem.cpp(125): Assertion failed: "crnlib_free: bad ptr" crunch/crnlib/crn_mem.cpp(125): Assertion failed: "crnlib_realloc: bad ptr" The usual malloc should already be aligned, but for some unknown reason it doesn't work on FreeBSD. Quote from `man malloc` on FreeBSD: > Standard API > The malloc() function allocates size bytes of uninitialized memory. The > allocated space is suitably aligned (after possible pointer coercion) > for storage of any type of object. This patch should not be needed. See #36
9ad2766
to
75bbda6
Compare
75bbda6
to
9e01210
Compare
This is not needed. |
But the tool doesn't run on some systems like FreeBSD without that… The patch does not look that intrusive. |
@slipher is there any performance impact at calling |
The FreeBSD malloc man page gives the same alignment guarantees as everyone else. There must be a memory corruption bug somewhere else. |
If I disable the tests for “bad ptr”, it works… |
@slipher what would be the drawback of using Because I can do an |
Adding complexity for no benefit. If you really think that FreeBSD malloc returns incorrect results, you can test that by putting the alignment assertion at the point of allocation rather than (or in addition to) where it is freed. |
diff --git a/crnlib/crn_mem.cpp b/crnlib/crn_mem.cpp
index 4040e4c..349f047 100644
--- a/crnlib/crn_mem.cpp
+++ b/crnlib/crn_mem.cpp
@@ -70,6 +70,10 @@ static void* crnlib_default_realloc(void* p, size_t size, size_t* pActual_size,
if (!p) {
p_new = ::malloc(size);
+ if ((ptr_bits_t)p_new & (CRNLIB_MIN_ALLOC_ALIGNMENT - 1)) {
+ crnlib_mem_error("crnlib_default_realloc: bad ptr");
+ return NULL;
+ }
CRNLIB_ASSERT((reinterpret_cast<ptr_bits_t>(p_new) & (CRNLIB_MIN_ALLOC_ALIGNMENT - 1)) == 0);
if (!p_new) {
@@ -160,11 +164,6 @@ void* crnlib_malloc(size_t size, size_t* pActual_size) {
}
void* crnlib_realloc(void* p, size_t size, size_t* pActual_size, bool movable) {
- if ((ptr_bits_t)p & (CRNLIB_MIN_ALLOC_ALIGNMENT - 1)) {
- crnlib_mem_error("crnlib_realloc: bad ptr");
- return NULL;
- }
-
if (size > CRNLIB_MAX_POSSIBLE_BLOCK_SIZE) {
crnlib_mem_error("crnlib_malloc: size too big");
return NULL; Before:
After:
On FreeBSD the alignment is already considered wrong right after the I don't know if that's a FreeBSD bug or if the alignment check itself is wrong. |
Seems like there is some heap corruption. Try it with address sanitizer or valgrind? |
When building with current Not running with
Running with
Valgrind simply hides the bug. |
I rebuilt with $ cmake .. \
-D'CMAKE_C_FLAGS'='-fsanitize=address' \
-D'CMAKE_CXX_FLAGS'='-fsanitize=address' \
-D'CMAKE_EXE_LINKER_FLAGS'='-fsanitize=address'
$ make -j$(sysctl -n hw.ncpu)
|
This fixes those errors experienced on FreeBSD: crunch/crnlib/crn_mem.cpp(125): Assertion failed: "crnlib_free: bad ptr" crunch/crnlib/crn_mem.cpp(125): Assertion failed: "crnlib_realloc: bad ptr" The usual malloc should already be aligned, but for some unknown reason it doesn't work on FreeBSD. See #36
9e01210
to
ccc3768
Compare
This fixes those errors experienced on FreeBSD: crunch/crnlib/crn_mem.cpp(125): Assertion failed: "crnlib_free: bad ptr" crunch/crnlib/crn_mem.cpp(125): Assertion failed: "crnlib_realloc: bad ptr" The usual malloc should already be aligned, but for some unknown reason it doesn't work on FreeBSD. Quote from `man malloc` on FreeBSD: > Standard API > The malloc() function allocates size bytes of uninitialized memory. The > allocated space is suitably aligned (after possible pointer coercion) > for storage of any type of object. This patch should not be needed. See #36
d42d81d
to
c504e8e
Compare
@slipher do you have other ideas to track possible heap corruptions? |
The workaround looks good enough to me, and is only used on the affected system, let's merge it. |
This fixes those errors experienced on FreeBSD:
The usual malloc should already be aligned, but for some unknown reason it doesn't work on FreeBSD.
Quote from
man malloc
on FreeBSD:This patch should not be needed.
Original message:
It's not bad to make sure every system does aligned allocation if we can, so let's use
aligned_alloc()
on Posix systems, which is meant to be freed with the samefree()
as the one used to freed memory allocated bymalloc()
:On macOS,
malloc()
is always aligned:Microsoft did not implemented
aligned_alloc()
, but implemented_aligned_malloc()
, but_aligned_malloc
requires allocated memory to be freed with_aligned_free()
, which would break compatibility with software freeing withfree()
:Using
_aligned_malloc()
instead ofmalloc()
on Windows produced a segmentation fault, somalloc()
is kept as is.