summaryrefslogtreecommitdiffstats
path: root/txr.1
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-06-23 20:53:11 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-06-23 20:53:11 -0700
commit2e0159fe467ac3ea9b89394ff2e8be77263a01d2 (patch)
treed4fe384b9f988823bc425b9f5072381aa9d681f1 /txr.1
parent6c901d9d33b5fed938114224434cad2f2c069592 (diff)
downloadtxr-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.180
1 files changed, 80 insertions, 0 deletions
diff --git a/txr.1 b/txr.1
index cdd9df69..79d3c78e 100644
--- a/txr.1
+++ b/txr.1
@@ -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