From: Gabor Melis Date: Wed, 24 Jun 2009 20:03:43 +0000 (+0000) Subject: 1.0.29.37: fix control stack exhuastion regression on x86 darwin X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=2b82a3b74bce63abaf496587eba08339ac938c91;p=sbcl.git 1.0.29.37: fix control stack exhuastion regression on x86 darwin ... caused by 1.0.29.32. https://bugs.launchpad.net/bugs/391620 --- diff --git a/src/runtime/interrupt.c b/src/runtime/interrupt.c index 294fc64..84ac00b 100644 --- a/src/runtime/interrupt.c +++ b/src/runtime/interrupt.c @@ -1485,19 +1485,37 @@ undefined_alien_function(void) funcall0(StaticSymbolFunction(UNDEFINED_ALIEN_FUNCTION_ERROR)); } +void lower_thread_control_stack_guard_page(struct thread *th) +{ + protect_control_stack_guard_page(0, th); + protect_control_stack_return_guard_page(1, th); + th->control_stack_guard_page_protected = NIL; + fprintf(stderr, "INFO: Control stack guard page unprotected\n"); +} + +void reset_thread_control_stack_guard_page(struct thread *th) +{ + memset(CONTROL_STACK_GUARD_PAGE(th), 0, os_vm_page_size); + protect_control_stack_guard_page(1, th); + protect_control_stack_return_guard_page(0, th); + th->control_stack_guard_page_protected = T; + fprintf(stderr, "INFO: Control stack guard page reprotected\n"); +} + /* Called from the REPL, too. */ void reset_control_stack_guard_page(void) { struct thread *th=arch_os_get_current_thread(); if (th->control_stack_guard_page_protected == NIL) { - memset(CONTROL_STACK_GUARD_PAGE(th), 0, os_vm_page_size); - protect_control_stack_guard_page(1, NULL); - protect_control_stack_return_guard_page(0, NULL); - th->control_stack_guard_page_protected = T; - fprintf(stderr, "INFO: Control stack guard page reprotected\n"); + reset_thread_control_stack_guard_page(th); } } +void lower_control_stack_guard_page(void) +{ + lower_thread_control_stack_guard_page(arch_os_get_current_thread()); +} + boolean handle_guard_page_triggered(os_context_t *context,os_vm_address_t addr) { @@ -1515,11 +1533,7 @@ handle_guard_page_triggered(os_context_t *context,os_vm_address_t addr) * and restore it. */ if (th->control_stack_guard_page_protected == NIL) lose("control_stack_guard_page_protected NIL"); - protect_control_stack_guard_page(0, NULL); - protect_control_stack_return_guard_page(1, NULL); - th->control_stack_guard_page_protected = NIL; - fprintf(stderr, "INFO: Control stack guard page unprotected\n"); - + lower_control_stack_guard_page(); #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK /* For the unfortunate case, when the control stack is * exhausted in a signal handler. */ diff --git a/src/runtime/interrupt.h b/src/runtime/interrupt.h index 93a5387..05c6638 100644 --- a/src/runtime/interrupt.h +++ b/src/runtime/interrupt.h @@ -166,4 +166,9 @@ extern void lisp_memory_fault_error(os_context_t *context, os_vm_address_t addr); #endif +#include "thread.h" + +extern void lower_thread_control_stack_guard_page(struct thread *th); +extern void reset_thread_control_stack_guard_page(struct thread *th); + #endif diff --git a/src/runtime/thread.h b/src/runtime/thread.h index 2f29aaa..eb653c1 100644 --- a/src/runtime/thread.h +++ b/src/runtime/thread.h @@ -8,7 +8,6 @@ #include "globals.h" #include "runtime.h" #include "os.h" -#include "interrupt.h" #ifdef LISP_FEATURE_GENCGC #include "gencgc-alloc-region.h" #else @@ -18,6 +17,7 @@ struct alloc_region { }; #include "genesis/static-symbols.h" #include "genesis/thread.h" #include "genesis/fdefn.h" +#include "interrupt.h" #define STATE_RUNNING (make_fixnum(1)) #define STATE_SUSPENDED (make_fixnum(2)) diff --git a/src/runtime/x86-64-darwin-os.c b/src/runtime/x86-64-darwin-os.c index bc42425..ed8abbb 100644 --- a/src/runtime/x86-64-darwin-os.c +++ b/src/runtime/x86-64-darwin-os.c @@ -352,8 +352,7 @@ catch_exception_raise(mach_port_t exception_port, * protection so the error handler has some headroom, protect the * previous page so that we can catch returns from the guard page * and restore it. */ - protect_control_stack_guard_page(0, th); - protect_control_stack_return_guard_page(1, th); + lower_thread_control_stack_guard_page(th); backup_thread_state = thread_state; open_stack_allocation(&thread_state); @@ -394,8 +393,7 @@ catch_exception_raise(mach_port_t exception_port, * unprotect this one. This works even if we somehow missed * the return-guard-page, and hit it on our way to new * exhaustion instead. */ - protect_control_stack_guard_page(1, th); - protect_control_stack_return_guard_page(0, th); + reset_thread_control_stack_guard_page(th); } else if (addr >= undefined_alien_address && addr < undefined_alien_address + os_vm_page_size) { diff --git a/src/runtime/x86-darwin-os.c b/src/runtime/x86-darwin-os.c index 25f13b1..ad41b0f 100644 --- a/src/runtime/x86-darwin-os.c +++ b/src/runtime/x86-darwin-os.c @@ -430,15 +430,13 @@ catch_exception_raise(mach_port_t exception_port, } /* At stack guard */ if (os_trunc_to_page(addr) == CONTROL_STACK_GUARD_PAGE(th)) { - protect_control_stack_guard_page(0, th); - protect_control_stack_return_guard_page(1, th); + lower_thread_control_stack_guard_page(th); handler = control_stack_exhausted_handler; break; } /* Return from stack guard */ if (os_trunc_to_page(addr) == CONTROL_STACK_RETURN_GUARD_PAGE(th)) { - protect_control_stack_guard_page(1, th); - protect_control_stack_return_guard_page(0, th); + reset_thread_control_stack_guard_page(th); break; } /* Regular memory fault */ diff --git a/version.lisp-expr b/version.lisp-expr index f580e61..1646dcc 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.29.36" +"1.0.29.37"