--- old/src/hotspot/os/posix/vmError_posix.cpp 2019-07-09 11:20:01.486432567 +0200 +++ new/src/hotspot/os/posix/vmError_posix.cpp 2019-07-09 11:20:01.346431181 +0200 @@ -132,8 +132,9 @@ // Needed because asserts may happen in error handling too. #ifdef CAN_SHOW_REGISTERS_ON_ASSERT if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) { - handle_assert_poison_fault(ucVoid, info->si_addr); - return; + if (handle_assert_poison_fault(ucVoid, info->si_addr)) { + return; + } } #endif // CAN_SHOW_REGISTERS_ON_ASSERT --- old/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp 2019-07-09 11:20:01.918436843 +0200 +++ new/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp 2019-07-09 11:20:01.774435418 +0200 @@ -306,8 +306,9 @@ #ifdef CAN_SHOW_REGISTERS_ON_ASSERT if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) { - handle_assert_poison_fault(ucVoid, info->si_addr); - return 1; + if (handle_assert_poison_fault(ucVoid, info->si_addr)) { + return 1; + } } #endif --- old/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp 2019-07-09 11:20:02.346441080 +0200 +++ new/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp 2019-07-09 11:20:02.202439655 +0200 @@ -301,8 +301,9 @@ #ifdef CAN_SHOW_REGISTERS_ON_ASSERT if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) { - handle_assert_poison_fault(ucVoid, info->si_addr); - return 1; + if (handle_assert_poison_fault(ucVoid, info->si_addr)) { + return 1; + } } #endif --- old/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp 2019-07-09 11:20:02.774445317 +0200 +++ new/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp 2019-07-09 11:20:02.630443892 +0200 @@ -271,8 +271,9 @@ #ifdef CAN_SHOW_REGISTERS_ON_ASSERT if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) { - handle_assert_poison_fault(ucVoid, info->si_addr); - return 1; + if (handle_assert_poison_fault(ucVoid, info->si_addr)) { + return 1; + } } #endif --- old/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp 2019-07-09 11:20:03.206449594 +0200 +++ new/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp 2019-07-09 11:20:03.062448168 +0200 @@ -270,8 +270,9 @@ #ifdef CAN_SHOW_REGISTERS_ON_ASSERT if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) { - handle_assert_poison_fault(ucVoid, info->si_addr); - return 1; + if (handle_assert_poison_fault(ucVoid, info->si_addr)) { + return 1; + } } #endif --- old/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp 2019-07-09 11:20:03.634453831 +0200 +++ new/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp 2019-07-09 11:20:03.494452445 +0200 @@ -510,8 +510,9 @@ #ifdef CAN_SHOW_REGISTERS_ON_ASSERT if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) { - handle_assert_poison_fault(ucVoid, info->si_addr); - return 1; + if (handle_assert_poison_fault(ucVoid, info->si_addr)) { + return 1; + } } #endif --- old/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp 2019-07-09 11:20:04.062458069 +0200 +++ new/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp 2019-07-09 11:20:03.918456642 +0200 @@ -303,8 +303,9 @@ #ifdef CAN_SHOW_REGISTERS_ON_ASSERT if ((sig == SIGSEGV || sig == SIGBUS) && info != NULL && info->si_addr == g_assert_poison) { - handle_assert_poison_fault(ucVoid, info->si_addr); - return 1; + if (handle_assert_poison_fault(ucVoid, info->si_addr)) { + return 1; + } } #endif --- old/src/hotspot/share/utilities/debug.cpp 2019-07-09 11:20:04.498462385 +0200 +++ new/src/hotspot/share/utilities/debug.cpp 2019-07-09 11:20:04.354460960 +0200 @@ -734,6 +734,10 @@ } } +void disarm_assert_poison() { + g_assert_poison = &g_dummy; +} + static void store_context(const void* context) { memcpy(&g_stored_assertion_context, context, sizeof(ucontext_t)); #if defined(__linux) && defined(PPC64) @@ -746,7 +750,14 @@ bool handle_assert_poison_fault(const void* ucVoid, const void* faulting_address) { if (faulting_address == g_assert_poison) { // Disarm poison page. - os::protect_memory((char*)g_assert_poison, os::vm_page_size(), os::MEM_PROT_RWX); + if (os::protect_memory((char*)g_assert_poison, os::vm_page_size(), os::MEM_PROT_RWX) == false) { +#ifdef ASSERT + fprintf(stderr, "Assertion poison page cannot be unprotected - mprotect failed with %d (%s)", + errno, os::strerror(errno)); + fflush(stderr); +#endif + return false; // unprotecting memory may fail in OOM situations, as surprising as this sounds. + } // Store Context away. if (ucVoid) { const intx my_tid = os::current_thread_id(); --- old/src/hotspot/share/utilities/debug.hpp 2019-07-09 11:20:04.930466662 +0200 +++ new/src/hotspot/share/utilities/debug.hpp 2019-07-09 11:20:04.782465197 +0200 @@ -37,6 +37,7 @@ extern char* g_assert_poison; #define TOUCH_ASSERT_POISON (*g_assert_poison) = 'X'; void initialize_assert_poison(); +void disarm_assert_poison(); bool handle_assert_poison_fault(const void* ucVoid, const void* faulting_address); #else #define TOUCH_ASSERT_POISON --- old/src/hotspot/share/utilities/vmError.cpp 2019-07-09 11:20:05.354470860 +0200 +++ new/src/hotspot/share/utilities/vmError.cpp 2019-07-09 11:20:05.210469434 +0200 @@ -1327,6 +1327,10 @@ // File descriptor to the error log file. static int fd_log = -1; + // Disarm assertion poison page, since from this point on we do not need this mechanism anymore and it may + // cause problems in error handling during native OOM, see JDK-8227275. + disarm_assert_poison(); + // Use local fdStream objects only. Do not use global instances whose initialization // relies on dynamic initialization (see JDK-8214975). Do not rely on these instances // to carry over into recursions or invocations from other threads.