Skip to content
This repository has been archived by the owner on Feb 2, 2023. It is now read-only.

Commit

Permalink
8227275: Within native OOM error handling, assertions may hang the pr…
Browse files Browse the repository at this point in the history
…ocess

Backport-of: ac0e723
  • Loading branch information
Ekaterina Vergizova authored and Yuri Nesterenko committed Feb 11, 2021
1 parent 9f7f443 commit 86ccee1
Show file tree
Hide file tree
Showing 10 changed files with 40 additions and 15 deletions.
5 changes: 3 additions & 2 deletions src/hotspot/os/posix/vmError_posix.cpp
Expand Up @@ -132,8 +132,9 @@ static void crash_handler(int sig, siginfo_t* info, void* ucVoid) {
// 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

Expand Down
5 changes: 3 additions & 2 deletions src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp
Expand Up @@ -242,8 +242,9 @@ JVM_handle_linux_signal(int sig,

#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

Expand Down
5 changes: 3 additions & 2 deletions src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp
Expand Up @@ -301,8 +301,9 @@ extern "C" int JVM_handle_linux_signal(int sig, siginfo_t* info,

#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

Expand Down
5 changes: 3 additions & 2 deletions src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp
Expand Up @@ -271,8 +271,9 @@ JVM_handle_linux_signal(int sig,

#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

Expand Down
5 changes: 3 additions & 2 deletions src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp
Expand Up @@ -270,8 +270,9 @@ JVM_handle_linux_signal(int sig,

#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

Expand Down
5 changes: 3 additions & 2 deletions src/hotspot/os_cpu/linux_sparc/os_linux_sparc.cpp
Expand Up @@ -510,8 +510,9 @@ JVM_handle_linux_signal(int sig,

#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

Expand Down
5 changes: 3 additions & 2 deletions src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp
Expand Up @@ -303,8 +303,9 @@ JVM_handle_linux_signal(int sig,

#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

Expand Down
13 changes: 12 additions & 1 deletion src/hotspot/share/utilities/debug.cpp
Expand Up @@ -734,6 +734,10 @@ void initialize_assert_poison() {
}
}

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)
Expand All @@ -746,7 +750,14 @@ static void store_context(const void* context) {
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();
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/utilities/debug.hpp
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions src/hotspot/share/utilities/vmError.cpp
Expand Up @@ -1336,6 +1336,12 @@ void VMError::report_and_die(int id, const char* message, const char* detail_fmt
// 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.
Expand Down

1 comment on commit 86ccee1

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.