Merge pull request #973 from ebarr24/codex/libc-posix-memalign-errors

fix(libc): return posix_memalign allocation errors
This commit is contained in:
Dean 2026-10-07 18:01:22 +13:00 committed by GitHub
commit 9ab937b261
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 41 additions and 4 deletions

View File

@ -226,7 +226,8 @@ int ApplicationHeapPosixAlign_nid_no_patch(void** pointer, std::size_t alignment
const auto align = callback<PosixAlign>(6);
CallbackScope scope;
void* result = nullptr;
if (align(&result, alignment, bytes) != 0) throw std::runtime_error("application heap: posix_memalign failed");
const int error = align(&result, alignment, bytes);
if (error != 0) return error;
requireAllocation(result);
if (reinterpret_cast<std::uintptr_t>(result) % alignment != 0) throw std::runtime_error("application heap: allocator returned a misaligned pointer");
*pointer = result;

View File

@ -246,7 +246,11 @@ void* APS5_VABI calloc_nid_postfix(size_t count, size_t size) {
}
int APS5_VABI posix_memalign_nid_postfix(void** pointer, size_t alignment, size_t size) {
return ApplicationHeapPosixAlign_nid_no_patch(pointer, alignment, size);
if (!pointer || alignment < sizeof(void*) || (alignment & (alignment - 1)) != 0) return 22;
const int savedError = errno;
const int result = ApplicationHeapPosixAlign_nid_no_patch(pointer, alignment, size);
errno = savedError;
return result;
}
void* APS5_VABI bsearch_nid_postfix(const void* key, const void* base, size_t count,

View File

@ -4,10 +4,13 @@
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <cstdio>
#include <limits>
#include <new>
#include <stdexcept>
extern "C" {
int APS5_VABI posix_memalign_nid_postfix(void**, std::size_t, std::size_t);
void* APS5_VABI _Znwm_nid_postfix(std::size_t);
void* APS5_VABI _ZnamRKSt9nothrow_t_nid_postfix(std::size_t, const void*);
void APS5_VABI _ZdlPv_nid_postfix(void*);
@ -25,10 +28,12 @@ namespace {
alignas(64) std::array<std::byte, 256> storage{};
std::size_t lastSize = 0;
std::size_t lastAlignment = 0;
unsigned posixCalls = 0;
unsigned initializes = 0;
unsigned frees = 0;
bool fail = false;
bool recurse = false;
bool nullPosixResult = false;
void require(bool condition) {
if (!condition) throw std::runtime_error("application heap test failed");
@ -79,7 +84,9 @@ void* APS5_VABI realign(void* pointer, std::size_t bytes, std::size_t alignment)
}
int APS5_VABI posixAlign(void** pointer, std::size_t alignment, std::size_t bytes) {
if (fail) return 12;
++posixCalls;
if (fail) { *__error_nid_postfix() = 12; *pointer = nullptr; return 12; }
if (nullPosixResult) { *pointer = nullptr; return 0; }
*pointer = align(alignment, bytes);
return 0;
}
@ -198,9 +205,34 @@ int main(int argc, char** argv) {
reject([] { ApplicationHeapAlign_nid_no_patch(4, 64); });
reject([] { ApplicationHeapAllocate_nid_no_patch(64); });
void* unchanged = storage.data();
reject([&] { ApplicationHeapPosixAlign_nid_no_patch(&unchanged, 64, 64); });
*__error_nid_postfix() = 77;
try {
const int error = posix_memalign_nid_postfix(&unchanged, 64, 64);
if (error != 12) { std::fprintf(stderr, "posix_memalign callback: expected ENOMEM 12, received %d\n", error); return 1; }
} catch (const std::exception&) {
std::fputs("posix_memalign callback: expected ENOMEM 12, received exception\n", stderr);
return 1;
}
require(*__error_nid_postfix() == 77);
require(unchanged == storage.data());
fail = false;
nullPosixResult = true;
bool rejectedNull = false;
try {
const int error = posix_memalign_nid_postfix(&unchanged, 64, 64);
std::fprintf(stderr, "posix_memalign callback: success with null pointer must throw, received %d\n", error);
return 1;
} catch (const std::bad_alloc&) { rejectedNull = true; }
require(rejectedNull && unchanged == storage.data());
nullPosixResult = false;
const auto beforeInvalid = posixCalls;
for (const std::size_t alignment : {std::size_t{0}, std::size_t{1}, std::size_t{4}, std::size_t{24}}) {
require(posix_memalign_nid_postfix(&unchanged, alignment, 32) == 22);
require(unchanged == storage.data() && *__error_nid_postfix() == 77);
}
require(posix_memalign_nid_postfix(nullptr, 64, 32) == 22 && posixCalls == beforeInvalid);
require(posix_memalign_nid_postfix(&unchanged, 64, 31) == 0 && unchanged == storage.data());
require(lastSize == 31 && lastAlignment == 64 && *__error_nid_postfix() == 77);
recurse = true;
reject([] { ApplicationHeapAllocate_nid_no_patch(64); });
recurse = false;