Merge pull request #973 from ebarr24/codex/libc-posix-memalign-errors
fix(libc): return posix_memalign allocation errors
This commit is contained in:
commit
9ab937b261
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue