# HG changeset patch # User stuefe # Date 1562821011 -7200 # Thu Jul 11 06:56:51 2019 +0200 # Node ID 5dc713c05d09c2272594ad8e1fde57f3b5dd5d52 # Parent 78bad98b410f749d79158baed6f66ecec6e71830 8227275: Within native OOM error handling, assertions may hang the process Reviewed-by: mdoerr, coleenp diff -r 78bad98b410f -r 5dc713c05d09 src/hotspot/os/posix/vmError_posix.cpp --- a/src/hotspot/os/posix/vmError_posix.cpp Wed Jun 05 09:12:45 2019 +0200 +++ b/src/hotspot/os/posix/vmError_posix.cpp Thu Jul 11 06:56:51 2019 +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 diff -r 78bad98b410f -r 5dc713c05d09 src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp --- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp Wed Jun 05 09:12:45 2019 +0200 +++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp Thu Jul 11 06:56:51 2019 +0200 @@ -243,8 +243,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 diff -r 78bad98b410f -r 5dc713c05d09 src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp --- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp Wed Jun 05 09:12:45 2019 +0200 +++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp Thu Jul 11 06:56:51 2019 +0200 @@ -310,8 +310,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 diff -r 78bad98b410f -r 5dc713c05d09 src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp --- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp Wed Jun 05 09:12:45 2019 +0200 +++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp Thu Jul 11 06:56:51 2019 +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 diff -r 78bad98b410f -r 5dc713c05d09 src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp --- a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp Wed Jun 05 09:12:45 2019 +0200 +++ b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp Thu Jul 11 06:56:51 2019 +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 diff -r 78bad98b410f -r 5dc713c05d09 src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp --- a/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp Wed Jun 05 09:12:45 2019 +0200 +++ b/src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp Thu Jul 11 06:56:51 2019 +0200 @@ -514,8 +514,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 diff -r 78bad98b410f -r 5dc713c05d09 src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp --- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp Wed Jun 05 09:12:45 2019 +0200 +++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp Thu Jul 11 06:56:51 2019 +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 diff -r 78bad98b410f -r 5dc713c05d09 src/hotspot/share/utilities/debug.cpp --- a/src/hotspot/share/utilities/debug.cpp Wed Jun 05 09:12:45 2019 +0200 +++ b/src/hotspot/share/utilities/debug.cpp Thu Jul 11 06:56:51 2019 +0200 @@ -732,6 +732,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) @@ -744,7 +748,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(); diff -r 78bad98b410f -r 5dc713c05d09 src/hotspot/share/utilities/debug.hpp --- a/src/hotspot/share/utilities/debug.hpp Wed Jun 05 09:12:45 2019 +0200 +++ b/src/hotspot/share/utilities/debug.hpp Thu Jul 11 06:56:51 2019 +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 diff -r 78bad98b410f -r 5dc713c05d09 src/hotspot/share/utilities/vmError.cpp --- a/src/hotspot/share/utilities/vmError.cpp Wed Jun 05 09:12:45 2019 +0200 +++ b/src/hotspot/share/utilities/vmError.cpp Thu Jul 11 06:56:51 2019 +0200 @@ -1315,6 +1315,12 @@ // File descriptor to the error log file. static int fd_log = -1; +#ifdef CAN_SHOW_REGISTERS_ON_ASSERT + // 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(); +#endif + // 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.