Fix fallout from the merge.

- CI merge issues:
   - The malloc shim libraries are renamed.
   - CMake gets very unhappy if you don't enable the C language and
     tries to link with the C compiler instead of the C++ compiler if
     you do enable it.
   - The Ubuntu packages for QEMU install a `binfmt_misc` activator for
     PowerPC64 little-endian, but set the page size to 4 KiB.  We then
     tried to run the tests (which expect 64 KiB pages) and became very
     confused when `mmap` returned 4 KiB-aligned memory.
 - Test failures:
   - Fix all of the issues UBsan found.
     - Underflow in `pointer_offset` when used to add negative offsets.
     - `CoreAlloc`'s `LocalState` accessed on a null `CoreAlloc` pointer.
     - Out of bounds access in the sizeclass list on attempts to access
       more memory than fits in the VA space.
     -
   - There was an integer overflow in `AddressSpace` that could cause it
     to try to allocate a zero-sized object, get a null pointer, and
     then try to do something with 0 - {size of the real allocation}.
   - The malloc tests weren't setting `errno` to 0 before doing
     calling `malloc`, which should set `errno` on failure, and then
     checking that `errno` was 0.
   - Don't call `PAL::error` on PAL allocation failure, return `nullptr`.
     The PALs were inconsistent about that and the new code expects to be
     able to report address-space exhaustion.
   - The malloc checks can behave differently with 0-sized allocations
     on different platforms but were very fragile about their
     expectations.
   - The malloc test didn't report failure for all of the ways that it
     could fail and so was spuriously passing on some platforms.
   - The perf test for external pointer is currently very slow on
     Windows.  The number of loops have been reduced and a timeout added
     for the Windows CI runs.
   - The logic to capture `errno` across calls was using
     `decltype(errno)`, which on some platforms where `errno` is a macro
     evaluated to `int&` and so they captured a reference rather than
     the value and failed to reset `errno`.
   - The Apple PAL can set `errno` on `notify_using` if it's called with
     memory that was not previously passed to `notify_not_using` but was
     not adequately protected against this and so would sometimes cause
     `malloc` to set `errno` to `EINVAL`.
This commit is contained in:
David Chisnall
2021-08-05 16:09:37 +01:00
parent e302ec0fa2
commit cd70a7856b
11 changed files with 49 additions and 22 deletions

View File

@@ -41,7 +41,7 @@ void check_result(size_t size, size_t align, void* p, int err, bool null)
#else
const auto exact_size = align == 1;
#endif
if (exact_size && (alloc_size != expected_size))
if (exact_size && (alloc_size != expected_size) && (size != 0))
{
printf(
"Usable size is %zu, but required to be %zu.\n",
@@ -79,7 +79,10 @@ void check_result(size_t size, size_t align, void* p, int err, bool null)
}
if (failed)
{
printf("check_result failed! %p", p);
abort();
}
our_free(p);
}
@@ -149,7 +152,9 @@ int main(int argc, char** argv)
{
const size_t size = bits::one_at_bit(sc);
printf("malloc: %zu\n", size);
errno = 0;
check_result(size, 1, our_malloc(size), SUCCESS, false);
errno = 0;
check_result(size + 1, 1, our_malloc(size + 1), SUCCESS, false);
}
@@ -180,7 +185,7 @@ int main(int argc, char** argv)
test_realloc(our_malloc(size), size, SUCCESS, false);
test_realloc(our_malloc(size), 0, SUCCESS, true);
test_realloc(nullptr, size, SUCCESS, false);
test_realloc(our_malloc(size), (size_t)-1, ENOMEM, true);
test_realloc(our_malloc(size), ((size_t)-1) / 2, ENOMEM, true);
for (sizeclass_t sc2 = 0; sc2 < NUM_SIZECLASSES; sc2++)
{
const size_t size2 = sizeclass_to_size(sc2);
@@ -195,7 +200,7 @@ int main(int argc, char** argv)
test_realloc(our_malloc(size), size, SUCCESS, false);
test_realloc(our_malloc(size), 0, SUCCESS, true);
test_realloc(nullptr, size, SUCCESS, false);
test_realloc(our_malloc(size), (size_t)-1, ENOMEM, true);
test_realloc(our_malloc(size), ((size_t)-1) / 2, ENOMEM, true);
for (sizeclass_t sc2 = 0; sc2 < (MAX_SIZECLASS_BITS + 4); sc2++)
{
const size_t size2 = bits::one_at_bit(sc2);
@@ -208,7 +213,7 @@ int main(int argc, char** argv)
test_realloc(our_malloc(64), 4194304, SUCCESS, false);
test_posix_memalign(0, 0, EINVAL, true);
test_posix_memalign((size_t)-1, 0, EINVAL, true);
test_posix_memalign(((size_t)-1) / 2, 0, EINVAL, true);
test_posix_memalign(OS_PAGE_SIZE, sizeof(uintptr_t) / 2, EINVAL, true);
for (size_t align = sizeof(uintptr_t); align < MAX_SIZECLASS_SIZE * 8;
@@ -222,7 +227,7 @@ int main(int argc, char** argv)
test_memalign(size, align, SUCCESS, false);
}
test_posix_memalign(0, align, SUCCESS, false);
test_posix_memalign((size_t)-1, align, ENOMEM, true);
test_posix_memalign(((size_t)-1) / 2, align, ENOMEM, true);
test_posix_memalign(0, align + 1, EINVAL, true);
}