8238988: Rename thread "in stack" methods and add in_stack_range
Reviewed-by: coleenp, dcubed
This commit is contained in:
parent
533649b8ca
commit
bd028945bd
src/hotspot
cpu
aarch64
arm
ppc
s390
sparc
x86
os
os_cpu
aix_ppc
bsd_x86
bsd_zero
linux_aarch64
linux_arm
linux_ppc
linux_s390
linux_sparc
linux_x86
linux_zero
solaris_sparc
solaris_x86
share
@ -76,16 +76,14 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
|
||||
// So unextended sp must be within the stack but we need not to check
|
||||
// that unextended sp >= sp
|
||||
|
||||
bool unextended_sp_safe = (unextended_sp < thread->stack_base());
|
||||
|
||||
if (!unextended_sp_safe) {
|
||||
if (!thread->is_in_full_stack(unextended_sp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// an fp must be within the stack and above (but not equal) sp
|
||||
// second evaluation on fp+ is added to handle situation where fp is -1
|
||||
bool fp_safe = (fp < thread->stack_base() && (fp > sp) && (((fp + (return_addr_offset * sizeof(void*))) < thread->stack_base())));
|
||||
bool fp_safe = thread->is_in_stack_range_excl(fp, sp) &&
|
||||
thread->is_in_full_stack(fp + (return_addr_offset * sizeof(void*)));
|
||||
|
||||
// We know sp/unextended_sp are safe only fp is questionable here
|
||||
|
||||
@ -147,7 +145,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
|
||||
sender_sp = _unextended_sp + _cb->frame_size();
|
||||
// Is sender_sp safe?
|
||||
if ((address)sender_sp >= thread->stack_base()) {
|
||||
if (!thread->is_in_full_stack((address)sender_sp)) {
|
||||
return false;
|
||||
}
|
||||
sender_unextended_sp = sender_sp;
|
||||
@ -164,9 +162,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
// only if the sender is interpreted/call_stub (c1 too?) are we certain that the saved fp
|
||||
// is really a frame pointer.
|
||||
|
||||
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
|
||||
|
||||
if (!saved_fp_safe) {
|
||||
if (!thread->is_in_stack_range_excl((address)saved_fp, (address)sender_sp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -201,9 +197,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
|
||||
// Could be the call_stub
|
||||
if (StubRoutines::returns_to_call_stub(sender_pc)) {
|
||||
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
|
||||
|
||||
if (!saved_fp_safe) {
|
||||
if (!thread->is_in_stack_range_excl((address)saved_fp, (address)sender_sp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -214,9 +208,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
// Validate the JavaCallWrapper an entry frame must have
|
||||
address jcw = (address)sender.entry_frame_call_wrapper();
|
||||
|
||||
bool jcw_safe = (jcw < thread->stack_base()) && (jcw > (address)sender.fp());
|
||||
|
||||
return jcw_safe;
|
||||
return thread->is_in_stack_range_excl(jcw, (address)sender.fp());
|
||||
}
|
||||
|
||||
CompiledMethod* nm = sender_blob->as_compiled_method_or_null();
|
||||
@ -557,11 +549,7 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
|
||||
// validate locals
|
||||
|
||||
address locals = (address) *interpreter_frame_locals_addr();
|
||||
|
||||
if (locals >= thread->stack_base() || locals < (address) fp()) return false;
|
||||
|
||||
// We'd have to be pretty unlucky to be mislead at this point
|
||||
return true;
|
||||
return thread->is_in_stack_range_incl(locals, (address)fp());
|
||||
}
|
||||
|
||||
BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) {
|
||||
|
@ -63,18 +63,13 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool unextended_sp_safe = (unextended_sp != NULL &&
|
||||
(unextended_sp < thread->stack_base()) &&
|
||||
(unextended_sp >= sp));
|
||||
if (!unextended_sp_safe) {
|
||||
if (!thread->is_in_stack_range_incl(unextended_sp, sp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We know sp/unextended_sp are safe. Only fp is questionable here.
|
||||
|
||||
bool fp_safe = (fp != NULL &&
|
||||
(fp < thread->stack_base()) &&
|
||||
fp >= sp);
|
||||
bool fp_safe = thread->is_in_stack_range_incl(fp, sp);
|
||||
|
||||
if (_cb != NULL ) {
|
||||
|
||||
@ -118,7 +113,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
|
||||
sender_sp = _unextended_sp + _cb->frame_size();
|
||||
// Is sender_sp safe?
|
||||
if ((address)sender_sp >= thread->stack_base()) {
|
||||
if (!thread->is_in_full_stack((address)sender_sp)) {
|
||||
return false;
|
||||
}
|
||||
// With our calling conventions, the return_address should
|
||||
@ -141,9 +136,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
// is really a frame pointer.
|
||||
|
||||
intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset + link_offset);
|
||||
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
|
||||
|
||||
if (!saved_fp_safe) {
|
||||
if (!thread->is_in_stack_range_excl((address)saved_fp, (address)sender_sp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -171,9 +164,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
// Could be the call_stub
|
||||
if (StubRoutines::returns_to_call_stub(sender_pc)) {
|
||||
intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset + link_offset);
|
||||
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
|
||||
|
||||
if (!saved_fp_safe) {
|
||||
if (!thread->is_in_stack_range_excl((address)saved_fp, (address)sender_sp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -184,9 +175,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
// Validate the JavaCallWrapper an entry frame must have
|
||||
address jcw = (address)sender.entry_frame_call_wrapper();
|
||||
|
||||
bool jcw_safe = (jcw < thread->stack_base()) && (jcw > (address)sender.fp());
|
||||
|
||||
return jcw_safe;
|
||||
return thread->is_in_stack_range_excl(jcw, (address)sender.fp());
|
||||
}
|
||||
|
||||
// If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
|
||||
@ -493,12 +482,7 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
|
||||
// validate locals
|
||||
|
||||
address locals = (address) *interpreter_frame_locals_addr();
|
||||
|
||||
if (locals >= thread->stack_base() || locals < (address) fp()) return false;
|
||||
|
||||
// We'd have to be pretty unlucky to be mislead at this point
|
||||
|
||||
return true;
|
||||
return thread->is_in_stack_range_incl(locals, (address)fp());
|
||||
}
|
||||
|
||||
BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) {
|
||||
|
@ -62,18 +62,15 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
}
|
||||
|
||||
// Unextended sp must be within the stack
|
||||
bool unextended_sp_safe = (unextended_sp < thread->stack_base());
|
||||
|
||||
if (!unextended_sp_safe) {
|
||||
if (!thread->is_in_full_stack(unextended_sp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// An fp must be within the stack and above (but not equal) sp.
|
||||
bool fp_safe = (fp < thread->stack_base()) && (fp > sp);
|
||||
bool fp_safe = thread->is_in_stack_range_excl(fp, sp);
|
||||
// An interpreter fp must be within the stack and above (but not equal) sp.
|
||||
// Moreover, it must be at least the size of the ijava_state structure.
|
||||
bool fp_interp_safe = (fp < thread->stack_base()) && (fp > sp) &&
|
||||
((fp - sp) >= ijava_state_size);
|
||||
bool fp_interp_safe = fp_safe && ((fp - sp) >= ijava_state_size);
|
||||
|
||||
// We know sp/unextended_sp are safe, only fp is questionable here
|
||||
|
||||
@ -132,7 +129,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
|
||||
// sender_fp must be within the stack and above (but not
|
||||
// equal) current frame's fp.
|
||||
if (sender_fp >= thread->stack_base() || sender_fp <= fp) {
|
||||
if (!thread->is_in_stack_range_excl(sender_fp, fp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -66,18 +66,15 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
}
|
||||
|
||||
// Unextended sp must be within the stack
|
||||
bool unextended_sp_safe = (unextended_sp < thread->stack_base());
|
||||
|
||||
if (!unextended_sp_safe) {
|
||||
if (!thread->is_in_full_stack(unextended_sp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// An fp must be within the stack and above (but not equal) sp.
|
||||
bool fp_safe = (fp < thread->stack_base()) && (fp > sp);
|
||||
bool fp_safe = thread->is_in_stack_range_excl(fp, sp);
|
||||
// An interpreter fp must be within the stack and above (but not equal) sp.
|
||||
// Moreover, it must be at least the size of the z_ijava_state structure.
|
||||
bool fp_interp_safe = (fp < thread->stack_base()) && (fp > sp) &&
|
||||
((fp - sp) >= z_ijava_state_size);
|
||||
bool fp_interp_safe = fp_safe && ((fp - sp) >= z_ijava_state_size);
|
||||
|
||||
// We know sp/unextended_sp are safe, only fp is questionable here
|
||||
|
||||
@ -136,7 +133,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
|
||||
// sender_fp must be within the stack and above (but not
|
||||
// equal) current frame's fp.
|
||||
if (sender_fp >= thread->stack_base() || sender_fp <= fp) {
|
||||
if (!thread->is_in_stack_range_excl(sender_fp, fp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -185,14 +185,12 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
}
|
||||
|
||||
// unextended sp must be within the stack and above or equal sp
|
||||
bool unextended_sp_safe = (_UNEXTENDED_SP < thread->stack_base()) &&
|
||||
(_UNEXTENDED_SP >= _SP);
|
||||
|
||||
if (!unextended_sp_safe) return false;
|
||||
if (!thread->is_in_stack_range_incl(_UNEXTENDED_SP, _SP)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// an fp must be within the stack and above (but not equal) sp
|
||||
bool fp_safe = (_FP < thread->stack_base()) &&
|
||||
(_FP > _SP);
|
||||
bool fp_safe = thread->is_in_stack_range_excl(_FP, _SP);
|
||||
|
||||
// We know sp/unextended_sp are safe only fp is questionable here
|
||||
|
||||
@ -251,10 +249,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
|
||||
// an fp must be within the stack and above (but not equal) current frame's _FP
|
||||
|
||||
bool sender_fp_safe = (sender_fp < thread->stack_base()) &&
|
||||
(sender_fp > _FP);
|
||||
|
||||
if (!sender_fp_safe) {
|
||||
if (!thread->is_in_stack_range_excl(sender_fp, _FP)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -276,12 +271,9 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
|
||||
if (sender.is_entry_frame()) {
|
||||
// Validate the JavaCallWrapper an entry frame must have
|
||||
|
||||
address jcw = (address)sender.entry_frame_call_wrapper();
|
||||
|
||||
bool jcw_safe = (jcw < thread->stack_base()) && (jcw > sender_fp);
|
||||
|
||||
return jcw_safe;
|
||||
return thread->is_in_stack_range_excl(jcw, sender_fp);
|
||||
}
|
||||
|
||||
// If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
|
||||
@ -670,11 +662,7 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
|
||||
// validate locals
|
||||
|
||||
address locals = (address) *interpreter_frame_locals_addr();
|
||||
|
||||
if (locals >= thread->stack_base() || locals < (address) fp()) return false;
|
||||
|
||||
// We'd have to be pretty unlucky to be mislead at this point
|
||||
return true;
|
||||
return thread->is_in_stack_range_incl(locals, (address)fp());
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,21 +63,19 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
}
|
||||
|
||||
// unextended sp must be within the stack and above or equal sp
|
||||
bool unextended_sp_safe = (unextended_sp < thread->stack_base()) &&
|
||||
(unextended_sp >= sp);
|
||||
|
||||
if (!unextended_sp_safe) {
|
||||
if (!thread->is_in_stack_range_incl(unextended_sp, sp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// an fp must be within the stack and above (but not equal) sp
|
||||
// second evaluation on fp+ is added to handle situation where fp is -1
|
||||
bool fp_safe = (fp < thread->stack_base() && (fp > sp) && (((fp + (return_addr_offset * sizeof(void*))) < thread->stack_base())));
|
||||
bool fp_safe = thread->is_in_stack_range_excl(fp, sp) &&
|
||||
thread->is_in_full_stack(fp + (return_addr_offset * sizeof(void*)));
|
||||
|
||||
// We know sp/unextended_sp are safe only fp is questionable here
|
||||
|
||||
// If the current frame is known to the code cache then we can attempt to
|
||||
// to construct the sender and do some validation of it. This goes a long way
|
||||
// construct the sender and do some validation of it. This goes a long way
|
||||
// toward eliminating issues when we get in frame construction code
|
||||
|
||||
if (_cb != NULL ) {
|
||||
@ -134,7 +132,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
|
||||
sender_sp = _unextended_sp + _cb->frame_size();
|
||||
// Is sender_sp safe?
|
||||
if ((address)sender_sp >= thread->stack_base()) {
|
||||
if (!thread->is_in_full_stack((address)sender_sp)) {
|
||||
return false;
|
||||
}
|
||||
sender_unextended_sp = sender_sp;
|
||||
@ -152,9 +150,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
// only if the sender is interpreted/call_stub (c1 too?) are we certain that the saved ebp
|
||||
// is really a frame pointer.
|
||||
|
||||
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
|
||||
|
||||
if (!saved_fp_safe) {
|
||||
if (!thread->is_in_stack_range_excl((address)saved_fp, (address)sender_sp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -189,9 +185,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
|
||||
// Could be the call_stub
|
||||
if (StubRoutines::returns_to_call_stub(sender_pc)) {
|
||||
bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
|
||||
|
||||
if (!saved_fp_safe) {
|
||||
if (!thread->is_in_stack_range_excl((address)saved_fp, (address)sender_sp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -202,9 +196,7 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
// Validate the JavaCallWrapper an entry frame must have
|
||||
address jcw = (address)sender.entry_frame_call_wrapper();
|
||||
|
||||
bool jcw_safe = (jcw < thread->stack_base()) && (jcw > (address)sender.fp());
|
||||
|
||||
return jcw_safe;
|
||||
return thread->is_in_stack_range_excl(jcw, (address)sender.fp());
|
||||
}
|
||||
|
||||
CompiledMethod* nm = sender_blob->as_compiled_method_or_null();
|
||||
@ -544,11 +536,7 @@ bool frame::is_interpreted_frame_valid(JavaThread* thread) const {
|
||||
// validate locals
|
||||
|
||||
address locals = (address) *interpreter_frame_locals_addr();
|
||||
|
||||
if (locals >= thread->stack_base() || locals < (address) fp()) return false;
|
||||
|
||||
// We'd have to be pretty unlucky to be mislead at this point
|
||||
return true;
|
||||
return thread->is_in_stack_range_incl(locals, (address)fp());
|
||||
}
|
||||
|
||||
BasicType frame::interpreter_frame_result(oop* oop_result, jvalue* value_result) {
|
||||
|
@ -718,7 +718,6 @@ void os::Linux::expand_stack_to(address bottom) {
|
||||
bool os::Linux::manually_expand_stack(JavaThread * t, address addr) {
|
||||
assert(t!=NULL, "just checking");
|
||||
assert(t->osthread()->expanding_stack(), "expand should be set");
|
||||
assert(t->stack_base() != NULL, "stack_base was not initialized");
|
||||
|
||||
if (t->is_in_usable_stack(addr)) {
|
||||
sigset_t mask_all, old_sigset;
|
||||
|
@ -539,13 +539,6 @@ void os::breakpoint() {
|
||||
BREAKPOINT;
|
||||
}
|
||||
|
||||
bool os::Solaris::valid_stack_address(Thread* thread, address sp) {
|
||||
address stackStart = (address)thread->stack_base();
|
||||
address stackEnd = (address)(stackStart - (address)thread->stack_size());
|
||||
if (sp < stackStart && sp >= stackEnd) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
extern "C" void breakpoint() {
|
||||
// use debugger to set breakpoint here
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -119,7 +119,6 @@ class Solaris {
|
||||
|
||||
static address handler_start, handler_end; // start and end pc of thr_sighndlrinfo
|
||||
|
||||
static bool valid_stack_address(Thread* thread, address sp);
|
||||
static bool valid_ucontext(Thread* thread, const ucontext_t* valid, const ucontext_t* suspect);
|
||||
static const ucontext_t* get_valid_uc_in_signal_handler(Thread* thread,
|
||||
const ucontext_t* uc);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2018 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -266,7 +266,7 @@ JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrec
|
||||
if (thread != NULL) {
|
||||
|
||||
// Handle ALL stack overflow variations here
|
||||
if (sig == SIGSEGV && thread->on_local_stack(addr)) {
|
||||
if (sig == SIGSEGV && thread->is_in_full_stack(addr)) {
|
||||
// stack overflow
|
||||
//
|
||||
// If we are in a yellow zone and we are inside java, we disable the yellow zone and
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -520,7 +520,7 @@ JVM_handle_bsd_signal(int sig,
|
||||
address addr = (address) info->si_addr;
|
||||
|
||||
// check if fault address is within thread stack
|
||||
if (thread->on_local_stack(addr)) {
|
||||
if (thread->is_in_full_stack(addr)) {
|
||||
// stack overflow
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
if (thread->thread_state() == _thread_in_Java) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -177,7 +177,7 @@ JVM_handle_bsd_signal(int sig,
|
||||
address addr = (address) info->si_addr;
|
||||
|
||||
// check if fault address is within thread stack
|
||||
if (thread->on_local_stack(addr)) {
|
||||
if (thread->is_in_full_stack(addr)) {
|
||||
// stack overflow
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -293,7 +293,7 @@ JVM_handle_linux_signal(int sig,
|
||||
// Handle ALL stack overflow variations here
|
||||
if (sig == SIGSEGV) {
|
||||
// check if fault address is within thread stack
|
||||
if (thread->on_local_stack(addr)) {
|
||||
if (thread->is_in_full_stack(addr)) {
|
||||
// stack overflow
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
if (thread->thread_state() == _thread_in_Java) {
|
||||
|
@ -336,7 +336,7 @@ extern "C" int JVM_handle_linux_signal(int sig, siginfo_t* info,
|
||||
return 1;
|
||||
}
|
||||
// check if fault address is within thread stack
|
||||
if (thread->on_local_stack(addr)) {
|
||||
if (thread->is_in_full_stack(addr)) {
|
||||
// stack overflow
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2019 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -326,7 +326,7 @@ JVM_handle_linux_signal(int sig,
|
||||
}
|
||||
|
||||
// Check if fault address is within thread stack.
|
||||
if (thread->on_local_stack(addr)) {
|
||||
if (thread->is_in_full_stack(addr)) {
|
||||
// stack overflow
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
if (thread->thread_state() == _thread_in_Java) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2016, 2019 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -321,7 +321,7 @@ JVM_handle_linux_signal(int sig,
|
||||
address addr = (address)info->si_addr; // Address causing SIGSEGV, usually mem ref target.
|
||||
|
||||
// Check if fault address is within thread stack.
|
||||
if (thread->on_local_stack(addr)) {
|
||||
if (thread->is_in_full_stack(addr)) {
|
||||
// stack overflow
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
if (thread->thread_state() == _thread_in_Java) {
|
||||
|
@ -63,7 +63,7 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
|
||||
|
||||
if (ret_frame.is_interpreted_frame()) {
|
||||
frame::z_ijava_state* istate = ret_frame.ijava_state_unchecked();
|
||||
if (on_local_stack((address)istate)) {
|
||||
if (is_in_full_stack((address)istate)) {
|
||||
return false;
|
||||
}
|
||||
const Method *m = (const Method*)(istate->method);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 20209, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -326,7 +326,7 @@ inline static bool checkOverflow(sigcontext* uc,
|
||||
JavaThread* thread,
|
||||
address* stub) {
|
||||
// check if fault address is within thread stack
|
||||
if (thread->on_local_stack(addr)) {
|
||||
if (thread->is_in_full_stack(addr)) {
|
||||
// stack overflow
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -359,7 +359,7 @@ JVM_handle_linux_signal(int sig,
|
||||
address addr = (address) info->si_addr;
|
||||
|
||||
// check if fault address is within thread stack
|
||||
if (thread->on_local_stack(addr)) {
|
||||
if (thread->is_in_full_stack(addr)) {
|
||||
// stack overflow
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
if (thread->thread_state() == _thread_in_Java) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright 2007, 2008, 2009, 2010 Red Hat, Inc.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -173,7 +173,7 @@ JVM_handle_linux_signal(int sig,
|
||||
address addr = (address) info->si_addr;
|
||||
|
||||
// check if fault address is within thread stack
|
||||
if (thread->on_local_stack(addr)) {
|
||||
if (thread->is_in_full_stack(addr)) {
|
||||
// stack overflow
|
||||
if (thread->in_stack_yellow_reserved_zone(addr)) {
|
||||
thread->disable_stack_yellow_reserved_zone();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -120,12 +120,12 @@ bool os::Solaris::valid_ucontext(Thread* thread, const ucontext_t* valid, const
|
||||
}
|
||||
|
||||
if (thread->is_Java_thread()) {
|
||||
if (!valid_stack_address(thread, (address)suspect)) {
|
||||
if (!thread->is_in_full_stack((address)suspect)) {
|
||||
DEBUG_ONLY(tty->print_cr("valid_ucontext: uc_link not in thread stack");)
|
||||
return false;
|
||||
}
|
||||
address _sp = (address)((intptr_t)suspect->uc_mcontext.gregs[REG_SP] + STACK_BIAS);
|
||||
if (!valid_stack_address(thread, _sp) ||
|
||||
if (!thread->is_in_full_stack(_sp) ||
|
||||
!frame::is_valid_stack_pointer(((JavaThread*)thread)->base_of_stack_pointer(), (intptr_t*)_sp)) {
|
||||
DEBUG_ONLY(tty->print_cr("valid_ucontext: stackpointer not in thread stack");)
|
||||
return false;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -140,11 +140,11 @@ bool os::Solaris::valid_ucontext(Thread* thread, const ucontext_t* valid, const
|
||||
}
|
||||
|
||||
if (thread->is_Java_thread()) {
|
||||
if (!valid_stack_address(thread, (address)suspect)) {
|
||||
if (!thread->is_in_full_stack((address)suspect)) {
|
||||
DEBUG_ONLY(tty->print_cr("valid_ucontext: uc_link not in thread stack");)
|
||||
return false;
|
||||
}
|
||||
if (!valid_stack_address(thread, (address) suspect->uc_mcontext.gregs[REG_SP])) {
|
||||
if (!thread->is_in_full_stack((address) suspect->uc_mcontext.gregs[REG_SP])) {
|
||||
DEBUG_ONLY(tty->print_cr("valid_ucontext: stackpointer not in thread stack");)
|
||||
return false;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -84,12 +84,12 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr,
|
||||
|
||||
// If sp and fp are nonsense just leave them out
|
||||
|
||||
if (!jt->on_local_stack((address)ret_sp)) {
|
||||
if (!jt->is_in_full_stack((address)ret_sp)) {
|
||||
ret_sp = NULL;
|
||||
ret_fp = NULL;
|
||||
} else {
|
||||
// sp is reasonable is fp reasonable?
|
||||
if ((address)ret_fp >= jt->stack_base() || ret_fp < ret_sp) {
|
||||
if (!jt->is_in_stack_range_incl((address)ret_fp, ret_sp)) {
|
||||
ret_fp = NULL;
|
||||
}
|
||||
}
|
||||
@ -102,4 +102,3 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr,
|
||||
}
|
||||
|
||||
void JavaThread::cache_global_variables() { }
|
||||
|
||||
|
@ -231,8 +231,7 @@ JavaCallWrapper* frame::entry_frame_call_wrapper_if_safe(JavaThread* thread) con
|
||||
bool frame::is_entry_frame_valid(JavaThread* thread) const {
|
||||
// Validate the JavaCallWrapper an entry frame must have
|
||||
address jcw = (address)entry_frame_call_wrapper();
|
||||
bool jcw_safe = (jcw < thread->stack_base()) && (jcw > (address)fp()); // less than stack base
|
||||
if (!jcw_safe) {
|
||||
if (!thread->is_in_stack_range_excl(jcw, (address)fp())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1284,17 +1283,17 @@ void FrameValues::print(JavaThread* thread) {
|
||||
intptr_t* v1 = _values.at(max_index).location;
|
||||
|
||||
if (thread == Thread::current()) {
|
||||
while (!thread->is_in_stack((address)v0)) {
|
||||
while (!thread->is_in_live_stack((address)v0)) {
|
||||
v0 = _values.at(++min_index).location;
|
||||
}
|
||||
while (!thread->is_in_stack((address)v1)) {
|
||||
while (!thread->is_in_live_stack((address)v1)) {
|
||||
v1 = _values.at(--max_index).location;
|
||||
}
|
||||
} else {
|
||||
while (!thread->on_local_stack((address)v0)) {
|
||||
while (!thread->is_in_full_stack((address)v0)) {
|
||||
v0 = _values.at(++min_index).location;
|
||||
}
|
||||
while (!thread->on_local_stack((address)v1)) {
|
||||
while (!thread->is_in_full_stack((address)v1)) {
|
||||
v1 = _values.at(--max_index).location;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -51,7 +51,7 @@ name##Handle::name##Handle(const name##Handle &h) { \
|
||||
} else { \
|
||||
_thread = Thread::current(); \
|
||||
} \
|
||||
assert (_thread->is_in_stack((address)this), "not on stack?"); \
|
||||
assert(_thread->is_in_live_stack((address)this), "not on stack?"); \
|
||||
_thread->metadata_handles()->push((Metadata*)_value); \
|
||||
} else { \
|
||||
_thread = NULL; \
|
||||
@ -68,7 +68,7 @@ name##Handle& name##Handle::operator=(const name##Handle &s) { \
|
||||
} else { \
|
||||
_thread = Thread::current(); \
|
||||
} \
|
||||
assert (_thread->is_in_stack((address)this), "not on stack?"); \
|
||||
assert(_thread->is_in_live_stack((address)this), "not on stack?"); \
|
||||
_thread->metadata_handles()->push((Metadata*)_value); \
|
||||
} else { \
|
||||
_thread = NULL; \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -59,7 +59,7 @@ inline name##Handle::name##Handle(Thread* thread, type* obj) : _value(obj), _thr
|
||||
if (obj != NULL) { \
|
||||
assert(((Metadata*)obj)->is_valid(), "obj is valid"); \
|
||||
assert(_thread == Thread::current(), "thread must be current"); \
|
||||
assert (_thread->is_in_stack((address)this), "not on stack?"); \
|
||||
assert(_thread->is_in_live_stack((address)this), "not on stack?"); \
|
||||
_thread->metadata_handles()->push((Metadata*)obj); \
|
||||
} \
|
||||
} \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -265,8 +265,7 @@ bool JNIHandles::is_frame_handle(JavaThread* thr, jobject handle) {
|
||||
// as the java command executable, in which case, this type of handle
|
||||
// is not permitted.
|
||||
return (thr->has_last_Java_frame() &&
|
||||
(void*)handle < (void*)thr->stack_base() &&
|
||||
(void*)handle >= (void*)thr->last_Java_sp());
|
||||
thr->is_in_stack_range_incl((address)handle, (address)thr->last_Java_sp()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1114,7 +1114,7 @@ void os::print_location(outputStream* st, intptr_t x, bool verbose) {
|
||||
}
|
||||
// If the addr is in the stack region for this thread then report that
|
||||
// and print thread info
|
||||
if (thread->on_local_stack(addr)) {
|
||||
if (thread->is_in_full_stack(addr)) {
|
||||
st->print_cr(INTPTR_FORMAT " is pointing into the stack for thread: "
|
||||
INTPTR_FORMAT, p2i(addr), p2i(thread));
|
||||
if (verbose) thread->print_on(st);
|
||||
|
@ -1018,20 +1018,13 @@ void Thread::check_for_valid_safepoint_state() {
|
||||
}
|
||||
#endif // ASSERT
|
||||
|
||||
// Check for adr in the live portion of our stack.
|
||||
bool Thread::is_in_stack(address adr) const {
|
||||
assert(Thread::current() == this, "is_in_stack can only be called from current thread");
|
||||
address end = os::current_stack_pointer();
|
||||
return (stack_base() > adr && adr >= end);
|
||||
}
|
||||
|
||||
// We had to move these methods here, because vm threads get into ObjectSynchronizer::enter
|
||||
// However, there is a note in JavaThread::is_lock_owned() about the VM threads not being
|
||||
// used for compilation in the future. If that change is made, the need for these methods
|
||||
// should be revisited, and they should be removed if possible.
|
||||
|
||||
bool Thread::is_lock_owned(address adr) const {
|
||||
return on_local_stack(adr);
|
||||
return is_in_full_stack(adr);
|
||||
}
|
||||
|
||||
bool Thread::set_as_starting_thread() {
|
||||
@ -1818,15 +1811,6 @@ bool JavaThread::reguard_stack(void) {
|
||||
return reguard_stack(os::current_stack_pointer());
|
||||
}
|
||||
|
||||
|
||||
// Check for adr in the usable portion of this thread's stack.
|
||||
bool JavaThread::is_in_usable_stack(address adr) const {
|
||||
size_t stack_guard_size = os::uses_stack_guard_pages() ? JavaThread::stack_guard_zone_size() : 0;
|
||||
size_t usable_stack_size = _stack_size - stack_guard_size;
|
||||
|
||||
return ((stack_base() > adr) && (adr >= (stack_base() - usable_stack_size)));
|
||||
}
|
||||
|
||||
void JavaThread::block_if_vm_exited() {
|
||||
if (_terminated == _vm_exited) {
|
||||
// _vm_exited is set at safepoint, and Threads_lock is never released
|
||||
|
@ -684,17 +684,42 @@ class Thread: public ThreadShadow {
|
||||
// jvmtiRedefineClasses support
|
||||
void metadata_handles_do(void f(Metadata*));
|
||||
|
||||
private:
|
||||
// Check if address is within the given range of this thread's
|
||||
// stack: stack_base() > adr >/>= limit
|
||||
// The check is inclusive of limit if passed true, else exclusive.
|
||||
bool is_in_stack_range(address adr, address limit, bool inclusive) const {
|
||||
assert(stack_base() > limit && limit >= stack_end(), "limit is outside of stack");
|
||||
return stack_base() > adr && (inclusive ? adr >= limit : adr > limit);
|
||||
}
|
||||
|
||||
public:
|
||||
// Used by fast lock support
|
||||
virtual bool is_lock_owned(address adr) const;
|
||||
|
||||
// Check if address is within the given range of this thread's
|
||||
// stack: stack_base() > adr >= limit
|
||||
bool is_in_stack_range_incl(address adr, address limit) const {
|
||||
return is_in_stack_range(adr, limit, true);
|
||||
}
|
||||
|
||||
// Check if address is within the given range of this thread's
|
||||
// stack: stack_base() > adr > limit
|
||||
bool is_in_stack_range_excl(address adr, address limit) const {
|
||||
return is_in_stack_range(adr, limit, false);
|
||||
}
|
||||
|
||||
// Check if address is in the stack mapped to this thread. Used mainly in
|
||||
// error reporting (so has to include guard zone) and frame printing.
|
||||
bool is_in_full_stack(address adr) const {
|
||||
return is_in_stack_range_incl(adr, stack_end());
|
||||
}
|
||||
|
||||
// Check if address is in the live stack of this thread (not just for locks).
|
||||
// Warning: can only be called by the current thread on itself.
|
||||
bool is_in_stack(address adr) const;
|
||||
|
||||
// Check if address in the stack mapped to this thread. Used mainly in
|
||||
// error reporting (so has to include guard zone) and frame printing.
|
||||
bool on_local_stack(address adr) const {
|
||||
return (_stack_base > adr && adr >= stack_end());
|
||||
bool is_in_live_stack(address adr) const {
|
||||
assert(Thread::current() == this, "is_in_live_stack can only be called from current thread");
|
||||
return is_in_stack_range_incl(adr, os::current_stack_pointer());
|
||||
}
|
||||
|
||||
// Sets this thread as starting thread. Returns failure if thread
|
||||
@ -1649,7 +1674,7 @@ class JavaThread: public Thread {
|
||||
assert(_stack_reserved_zone_size == 0, "This should be called only once.");
|
||||
_stack_reserved_zone_size = s;
|
||||
}
|
||||
address stack_reserved_zone_base() {
|
||||
address stack_reserved_zone_base() const {
|
||||
return (address)(stack_end() +
|
||||
(stack_red_zone_size() + stack_yellow_zone_size() + stack_reserved_zone_size()));
|
||||
}
|
||||
@ -1732,8 +1757,10 @@ class JavaThread: public Thread {
|
||||
|
||||
// Check if address is in the usable part of the stack (excludes protected
|
||||
// guard pages). Can be applied to any thread and is an approximation for
|
||||
// using is_in_stack when the query has to happen from another thread.
|
||||
bool is_in_usable_stack(address adr) const;
|
||||
// using is_in_live_stack when the query has to happen from another thread.
|
||||
bool is_in_usable_stack(address adr) const {
|
||||
return is_in_stack_range_incl(adr, stack_reserved_zone_base());
|
||||
}
|
||||
|
||||
// Misc. accessors/mutators
|
||||
void set_do_not_unlock(void) { _do_not_unlock_if_synchronized = true; }
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -58,8 +58,9 @@ void UnhandledOops::dump_oops(UnhandledOops *list) {
|
||||
static Thread* unhandled_oop_print = NULL;
|
||||
|
||||
void UnhandledOops::register_unhandled_oop(oop* op, address pc) {
|
||||
if (!_thread->is_in_stack((address)op))
|
||||
if (!_thread->is_in_live_stack((address)op)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_level++;
|
||||
if (unhandled_oop_print == _thread) {
|
||||
@ -96,7 +97,7 @@ void UnhandledOops::allow_unhandled_oop(oop* op) {
|
||||
// oop list. All oops given are assumed to be on the list. If not,
|
||||
// there's a bug in the unhandled oop detector.
|
||||
void UnhandledOops::unregister_unhandled_oop(oop* op) {
|
||||
if (!_thread->is_in_stack((address)op)) return;
|
||||
if (!_thread->is_in_live_stack((address)op)) return;
|
||||
|
||||
if (unhandled_oop_print == _thread) {
|
||||
for (int i=0; i < _level; i++) tty->print(" ");
|
||||
@ -117,7 +118,7 @@ void UnhandledOops::clear_unhandled_oops() {
|
||||
// If an entry is on the unhandled oop list but isn't on the stack
|
||||
// anymore, it must not have gotten unregistered properly and it's a bug
|
||||
// in the unhandled oop generator.
|
||||
if(!_thread->is_in_stack((address)entry._oop_ptr)) {
|
||||
if (!_thread->is_in_live_stack((address)entry._oop_ptr)) {
|
||||
tty->print_cr("oop_ptr is " INTPTR_FORMAT, p2i(entry._oop_ptr));
|
||||
tty->print_cr("thread is " INTPTR_FORMAT " from pc " INTPTR_FORMAT,
|
||||
p2i(_thread), p2i(entry._pc));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -251,7 +251,7 @@ void VMError::print_native_stack(outputStream* st, frame fr, Thread* t, char* bu
|
||||
if (t && t->is_Java_thread()) {
|
||||
// Catch very first native frame by using stack address.
|
||||
// For JavaThread stack_base and stack_size should be set.
|
||||
if (!t->on_local_stack((address)(fr.real_fp() + 1))) {
|
||||
if (!t->is_in_full_stack((address)(fr.real_fp() + 1))) {
|
||||
break;
|
||||
}
|
||||
if (fr.is_java_frame() || fr.is_native_frame() || fr.is_runtime_frame()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user