Merge pull request #1001 from Dextroid17/fix/application-heap-finalize-order
fix(libc): register the application heap finalizer when libc loads
This commit is contained in:
commit
2129a6ef29
|
|
@ -242,8 +242,9 @@ if(BUILD_TESTING)
|
|||
add_test(NAME application_heap_replacement COMMAND application_heap_tests)
|
||||
add_test(NAME application_heap_invalid_metadata COMMAND application_heap_tests invalid)
|
||||
add_test(NAME application_heap_default COMMAND application_heap_tests default)
|
||||
add_test(NAME application_heap_exit_order COMMAND application_heap_tests exit-order)
|
||||
if(WIN32)
|
||||
set_tests_properties(application_heap_replacement application_heap_invalid_metadata application_heap_default
|
||||
set_tests_properties(application_heap_replacement application_heap_invalid_metadata application_heap_default application_heap_exit_order
|
||||
PROPERTIES ENVIRONMENT_MODIFICATION "PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -95,11 +95,10 @@ void requireAlignment(std::size_t alignment) {
|
|||
}
|
||||
|
||||
void finalize() {
|
||||
Initialize finalizeCallback;
|
||||
Initialize finalizeCallback = nullptr;
|
||||
{
|
||||
std::lock_guard lock(heapMutex);
|
||||
if (heapFailure) std::rethrow_exception(heapFailure);
|
||||
if (heapFinalized) throw std::runtime_error("application heap: duplicate finalization");
|
||||
if (heapFinalized || heapFailure) return;
|
||||
finalizeCallback = heapFinalize;
|
||||
}
|
||||
if (finalizeCallback != nullptr) finalizeCallback();
|
||||
|
|
@ -107,6 +106,13 @@ void finalize() {
|
|||
heapFinalized = true;
|
||||
}
|
||||
|
||||
struct HeapFinalizerRegistration {
|
||||
HeapFinalizerRegistration() {
|
||||
if (std::atexit(finalize) != 0) std::terminate();
|
||||
}
|
||||
};
|
||||
const HeapFinalizerRegistration heapFinalizerRegistration;
|
||||
|
||||
}
|
||||
|
||||
void ApplicationHeapRegister_nid_no_patch(void* const* api) {
|
||||
|
|
@ -144,7 +150,6 @@ void ApplicationHeapInitialize_nid_no_patch(const void* processParameters) {
|
|||
std::lock_guard lock(heapMutex);
|
||||
heapFinalize = read<Initialize>(replacement, 0x18);
|
||||
}
|
||||
if (std::atexit(finalize) != 0) throw std::runtime_error("application heap: cannot register finalization");
|
||||
} catch (...) {
|
||||
std::lock_guard lock(heapMutex);
|
||||
heapFailure = std::current_exception();
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ void* ApplicationHeapRealign_nid_no_patch(void*, std::size_t, std::size_t);
|
|||
char* APS5_VABI strdup_nid_postfix(const char*);
|
||||
char* APS5_VABI strndup_nid_postfix(const char*, std::size_t);
|
||||
int* APS5_VABI __error_nid_postfix();
|
||||
int APS5_VABI atexit_nid_postfix(void (APS5_VABI*)());
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
@ -42,6 +43,9 @@ void reject(TAction action) {
|
|||
|
||||
void APS5_VABI initialize() { ++initializes; }
|
||||
void APS5_VABI finalize() { require(initializes == 1); }
|
||||
void APS5_VABI exitCallbackAllocates() {
|
||||
if (ApplicationHeapAllocate_nid_no_patch(16) != storage.data()) throw std::runtime_error("application heap test failed");
|
||||
}
|
||||
|
||||
void* APS5_VABI allocate(std::size_t bytes) {
|
||||
lastSize = bytes;
|
||||
|
|
@ -110,6 +114,12 @@ int main(int argc, char** argv) {
|
|||
write(replacement, 0x40, &align);
|
||||
write(replacement, 0x48, &realign);
|
||||
write(replacement, 0x50, &posixAlign);
|
||||
if (argc > 1 && std::strcmp(argv[1], "exit-order") == 0) {
|
||||
require(atexit_nid_postfix(exitCallbackAllocates) == 0);
|
||||
ApplicationHeapInitialize_nid_no_patch(process.data());
|
||||
require(initializes == 1);
|
||||
return 0;
|
||||
}
|
||||
if (argc > 1 && std::strcmp(argv[1], "default") == 0) {
|
||||
std::array<void*, 10> partial{};
|
||||
partial[0] = reinterpret_cast<void*>(&allocate);
|
||||
|
|
|
|||
Loading…
Reference in New Issue