diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2021-06-23 20:53:11 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2021-06-23 20:53:11 -0700 |
commit | 2e0159fe467ac3ea9b89394ff2e8be77263a01d2 (patch) | |
tree | d4fe384b9f988823bc425b9f5072381aa9d681f1 /txr.1 | |
parent | 6c901d9d33b5fed938114224434cad2f2c069592 (diff) | |
download | txr-2e0159fe467ac3ea9b89394ff2e8be77263a01d2.tar.gz txr-2e0159fe467ac3ea9b89394ff2e8be77263a01d2.tar.bz2 txr-2e0159fe467ac3ea9b89394ff2e8be77263a01d2.zip |
New: stack overflow protection.
* configure: detect getrlimit, producing HAVE_RLIMIT in
config.h.
* eval.c (do_eval, do_expand): Call gc_stack_check inline
function to check stack pointer against limit.
* gc.c (gc_stack_bottom): Static becomes extern, so inline
function in gc.h can refer to it.
(gc_stack_limit): New global variable.
(gc_init): If we have rlimit, then probe RLIMIT_STACK.
If the stack is sufficiently large, then enable the stack
overflow protection, which kicks in when the stack pointer
appears to be within a certain percentage of the limit.
(set_stack_limit, get_stack_limit): New static functions.
(gc_late_init): Register set-stack-limit and get-stack-limit
intrinsics.
(gc_stack_overflow): New function.
* gc.h (gc_stack_bottom, gc_stack_limit, gc_stack_overflow):
Declared.
(gc_stack_check): New inline function.
* lib.c (stack_overflow_s): New symbol variable.
(obj_print_impl): Call gc_stack_check to protect recursive
printing againts overflow.
* lib.h (stack_overflow_s): Declared.
* unwind.c (uw_init): Register stack-overflow symbol as a an
exception symbol subtyped from error.
(uw_unwind_to_exit_point): When dealing with an unhandled
exception, turn off the stack limit, so we can print the
messages without triggering it in a loop.
* vm.c (vm_execute_closure, vm_funcall_common): Insert
gc_stack_check to the top of the execution of every VM
function.
* txr.1: Documented.
* share/txr/stdlib/doc-syms.tl: Updated.
Diffstat (limited to 'txr.1')
-rw-r--r-- | txr.1 | 80 |
1 files changed, 80 insertions, 0 deletions
@@ -72284,6 +72284,86 @@ only correct under an explicit .code call-finalizers but incorrect under spontaneous reclamation driven by garbage collection. +.SS* Stack Overflow Protection + +\*(TX features a rudimentary mechanism for guarding against stack overflow +situations, which cause the \*(TX process to crash. This capability is separate +from and exists in addition to the possibility of catching a +.code sig-segv +(segmentation violation) signal upon stack overflow using +.codn set-sig-handler . + +The stack overflow guard mechanism is based on \*(TX, at certain key places +in the execution, checking the current position of the stack relative to +a predetermined limit. If the position exceeds the limit, then an exception +of type +.codn stack-overflow , +derived from +.codn error , +is thrown. + +The stack overflow guard mechanism is enabled at startup on those platforms +where it is possible to inquire the system about the stack limit, and where the +stack limit is at least 512 kilobytes. \*(TX configures the limit to within a +certain percentage of the actual value. If it is not possible to determine the +system's stack limit, or it is too low, then the mechanism is disabled. + +The +.code get-stack-limit +and +.code set-stack-limit +functions are provided to manipulate the stack limit. + +The mechanism cannot contain absolutely all sources of stack overflow threat +under all conditions. External functions are not protected, and not all +internal functions are monitored. If \*(TX is close to the limit, but +a function is called whose stack growth is not monitored, such as +an external function or unmonitored internal function, it is possible that +the stack may overflow anyway. + +.coNP Functions @ get-stack-limit and @ set-stack-limit +.synb +.mets (get-stack-limit) +.mets (set-stack-limit << value ) +.syne +.desc +The +.code get-stack-limit +returns the current value of the stack limit. If the guard mechanism is +not enabled, it returns +.codn nil , +otherwise it returns a positive integer, which is measured in bytes. + +The +.code set-stack-limit +configures the stack limit according to +.metn value , +possibly enabling or disabling the guard mechanism, and returns the previous +stack limit in exactly the same manner as +.codn get-stack-limit . + +The +.meta value +must be a non-negative integer or else the symbol +.codn nil . + +The values zero or +.code nil +disable the guard mechanism. Positive integer values set the limit. +The value may be truncated to a multiple of some denomination or +otherwise adjusted, so that a subsequent call to +.code get-stack-limit +need not retrieve that exact value. + +If +.meta value +is too close to the system stack limit or beyond, the effectiveness +of the stack overflow detection mechanism is compromised. +Likewise, if +.meta value +is too low, the operation of \*(TX shall become unreliable. Values +smaller than 326767 bytes are strongly discouraged. + .SS* Modularization .coNP Variable @ self-path .desc |