mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-17 17:44:40 +02:00
8139864: Improve handling of stack protection zones
Reviewed-by: stuefe, coleenp, fparain
This commit is contained in:
parent
8c13cfe16c
commit
b5bca5cc1b
43 changed files with 314 additions and 228 deletions
|
@ -319,8 +319,7 @@ void Thread::record_stack_base_and_size() {
|
|||
|
||||
#if INCLUDE_NMT
|
||||
// record thread's native stack, stack grows downward
|
||||
address stack_low_addr = stack_base() - stack_size();
|
||||
MemTracker::record_thread_stack(stack_low_addr, stack_size());
|
||||
MemTracker::record_thread_stack(stack_end(), stack_size());
|
||||
#endif // INCLUDE_NMT
|
||||
}
|
||||
|
||||
|
@ -337,8 +336,7 @@ Thread::~Thread() {
|
|||
// not proper way to enforce that.
|
||||
#if INCLUDE_NMT
|
||||
if (_stack_base != NULL) {
|
||||
address low_stack_addr = stack_base() - stack_size();
|
||||
MemTracker::release_thread_stack(low_stack_addr, stack_size());
|
||||
MemTracker::release_thread_stack(stack_end(), stack_size());
|
||||
#ifdef ASSERT
|
||||
set_stack_base(NULL);
|
||||
#endif
|
||||
|
@ -821,7 +819,7 @@ void Thread::print_on_error(outputStream* st, char* buf, int buflen) const {
|
|||
else st->print("Thread");
|
||||
|
||||
st->print(" [stack: " PTR_FORMAT "," PTR_FORMAT "]",
|
||||
p2i(_stack_base - _stack_size), p2i(_stack_base));
|
||||
p2i(stack_end()), p2i(stack_base()));
|
||||
|
||||
if (osthread()) {
|
||||
st->print(" [id=%d]", osthread()->thread_id());
|
||||
|
@ -907,9 +905,8 @@ bool Thread::is_in_stack(address adr) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool Thread::is_in_usable_stack(address adr) const {
|
||||
size_t stack_guard_size = os::uses_stack_guard_pages() ? (StackReservedPages + StackYellowPages + StackRedPages) * os::vm_page_size() : 0;
|
||||
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 ((adr < stack_base()) && (adr >= stack_base() - usable_stack_size));
|
||||
|
@ -1534,7 +1531,7 @@ JavaThread::JavaThread(bool is_attaching_via_jni) :
|
|||
}
|
||||
|
||||
bool JavaThread::reguard_stack(address cur_sp) {
|
||||
if (_stack_guard_state != stack_guard_yellow_disabled
|
||||
if (_stack_guard_state != stack_guard_yellow_reserved_disabled
|
||||
&& _stack_guard_state != stack_guard_reserved_disabled) {
|
||||
return true; // Stack already guarded or guard pages not needed.
|
||||
}
|
||||
|
@ -1551,9 +1548,10 @@ bool JavaThread::reguard_stack(address cur_sp) {
|
|||
// is executing there, either StackShadowPages should be larger, or
|
||||
// some exception code in c1, c2 or the interpreter isn't unwinding
|
||||
// when it should.
|
||||
guarantee(cur_sp > stack_yellow_zone_base(), "not enough space to reguard - increase StackShadowPages");
|
||||
if (_stack_guard_state == stack_guard_yellow_disabled) {
|
||||
enable_stack_yellow_zone();
|
||||
guarantee(cur_sp > stack_reserved_zone_base(),
|
||||
"not enough space to reguard - increase StackShadowPages");
|
||||
if (_stack_guard_state == stack_guard_yellow_reserved_disabled) {
|
||||
enable_stack_yellow_reserved_zone();
|
||||
if (reserved_stack_activation() != stack_base()) {
|
||||
set_reserved_stack_activation(stack_base());
|
||||
}
|
||||
|
@ -2480,10 +2478,15 @@ void JavaThread::java_resume() {
|
|||
}
|
||||
}
|
||||
|
||||
size_t JavaThread::_stack_red_zone_size = 0;
|
||||
size_t JavaThread::_stack_yellow_zone_size = 0;
|
||||
size_t JavaThread::_stack_reserved_zone_size = 0;
|
||||
size_t JavaThread::_stack_shadow_zone_size = 0;
|
||||
|
||||
void JavaThread::create_stack_guard_pages() {
|
||||
if (! os::uses_stack_guard_pages() || _stack_guard_state != stack_guard_unused) return;
|
||||
address low_addr = stack_base() - stack_size();
|
||||
size_t len = (StackReservedPages + StackYellowPages + StackRedPages) * os::vm_page_size();
|
||||
if (!os::uses_stack_guard_pages() || _stack_guard_state != stack_guard_unused) { return; }
|
||||
address low_addr = stack_end();
|
||||
size_t len = stack_guard_zone_size();
|
||||
|
||||
int allocate = os::allocate_stack_guard_pages();
|
||||
// warning("Guarding at " PTR_FORMAT " for len " SIZE_FORMAT "\n", low_addr, len);
|
||||
|
@ -2506,8 +2509,8 @@ void JavaThread::create_stack_guard_pages() {
|
|||
void JavaThread::remove_stack_guard_pages() {
|
||||
assert(Thread::current() == this, "from different thread");
|
||||
if (_stack_guard_state == stack_guard_unused) return;
|
||||
address low_addr = stack_base() - stack_size();
|
||||
size_t len = (StackReservedPages + StackYellowPages + StackRedPages) * os::vm_page_size();
|
||||
address low_addr = stack_end();
|
||||
size_t len = stack_guard_zone_size();
|
||||
|
||||
if (os::allocate_stack_guard_pages()) {
|
||||
if (os::remove_stack_guard_pages((char *) low_addr, len)) {
|
||||
|
@ -2563,18 +2566,18 @@ void JavaThread::disable_stack_reserved_zone() {
|
|||
disable_register_stack_guard();
|
||||
}
|
||||
|
||||
void JavaThread::enable_stack_yellow_zone() {
|
||||
void JavaThread::enable_stack_yellow_reserved_zone() {
|
||||
assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
|
||||
assert(_stack_guard_state != stack_guard_enabled, "already enabled");
|
||||
|
||||
// The base notation is from the stacks point of view, growing downward.
|
||||
// We need to adjust it to work correctly with guard_memory()
|
||||
address base = stack_yellow_zone_base() - stack_yellow_zone_size();
|
||||
address base = stack_red_zone_base();
|
||||
|
||||
guarantee(base < stack_base(), "Error calculating stack yellow zone");
|
||||
guarantee(base < os::current_stack_pointer(), "Error calculating stack yellow zone");
|
||||
|
||||
if (os::guard_memory((char *) base, stack_yellow_zone_size())) {
|
||||
if (os::guard_memory((char *) base, stack_yellow_reserved_zone_size())) {
|
||||
_stack_guard_state = stack_guard_enabled;
|
||||
} else {
|
||||
warning("Attempt to guard stack yellow zone failed.");
|
||||
|
@ -2582,19 +2585,19 @@ void JavaThread::enable_stack_yellow_zone() {
|
|||
enable_register_stack_guard();
|
||||
}
|
||||
|
||||
void JavaThread::disable_stack_yellow_zone() {
|
||||
void JavaThread::disable_stack_yellow_reserved_zone() {
|
||||
assert(_stack_guard_state != stack_guard_unused, "must be using guard pages.");
|
||||
assert(_stack_guard_state != stack_guard_yellow_disabled, "already disabled");
|
||||
assert(_stack_guard_state != stack_guard_yellow_reserved_disabled, "already disabled");
|
||||
|
||||
// Simply return if called for a thread that does not use guard pages.
|
||||
if (_stack_guard_state == stack_guard_unused) return;
|
||||
|
||||
// The base notation is from the stacks point of view, growing downward.
|
||||
// We need to adjust it to work correctly with guard_memory()
|
||||
address base = stack_yellow_zone_base() - stack_yellow_zone_size();
|
||||
address base = stack_red_zone_base();
|
||||
|
||||
if (os::unguard_memory((char *)base, stack_yellow_zone_size())) {
|
||||
_stack_guard_state = stack_guard_yellow_disabled;
|
||||
if (os::unguard_memory((char *)base, stack_yellow_reserved_zone_size())) {
|
||||
_stack_guard_state = stack_guard_yellow_reserved_disabled;
|
||||
} else {
|
||||
warning("Attempt to unguard stack yellow zone failed.");
|
||||
}
|
||||
|
@ -2899,7 +2902,7 @@ void JavaThread::print_on_error(outputStream* st, char *buf, int buflen) const {
|
|||
st->print(", id=%d", osthread()->thread_id());
|
||||
}
|
||||
st->print(", stack(" PTR_FORMAT "," PTR_FORMAT ")",
|
||||
p2i(_stack_base - _stack_size), p2i(_stack_base));
|
||||
p2i(stack_end()), p2i(stack_base()));
|
||||
st->print("]");
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue