[25] | 1 | # Tests that the stack size is big enough for the application. |
---|
| 2 | # |
---|
| 3 | # This file contains a collection of tests for one or more of the Tcl |
---|
| 4 | # built-in commands. Sourcing this file into Tcl runs the tests and |
---|
| 5 | # generates output for errors. No output means no errors were found. |
---|
| 6 | # |
---|
| 7 | # Copyright (c) 1998-2000 Ajuba Solutions. |
---|
| 8 | # |
---|
| 9 | # See the file "license.terms" for information on usage and redistribution |
---|
| 10 | # of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
---|
| 11 | # |
---|
| 12 | # RCS: @(#) $Id: stack.test,v 1.22 2007/12/13 15:26:07 dgp Exp $ |
---|
| 13 | |
---|
| 14 | if {[lsearch [namespace children] ::tcltest] == -1} { |
---|
| 15 | package require tcltest 2 |
---|
| 16 | namespace import -force ::tcltest::* |
---|
| 17 | } |
---|
| 18 | |
---|
| 19 | # Note that a failure in this test results in a crash of the executable. |
---|
| 20 | # In order to avoid that, we do a basic check of the current stacksize. |
---|
| 21 | # This size can be changed with ulimit (ksh/bash/sh) or limit (csh/tcsh). |
---|
| 22 | |
---|
| 23 | # This doesn't catch all cases, for example threads of lower stacksize |
---|
| 24 | # can still squeak through. A core check is really needed. -- JH |
---|
| 25 | |
---|
| 26 | testConstraint minStack2400 1 |
---|
| 27 | if {[testConstraint unix]} { |
---|
| 28 | set stackSize [exec /bin/sh -c "ulimit -s"] |
---|
| 29 | if {[string is integer $stackSize] && ($stackSize < 2400)} { |
---|
| 30 | puts stderr "WARNING: the default application stacksize of $stackSize\ |
---|
| 31 | may cause Tcl to\ncrash due to stack overflow before the\ |
---|
| 32 | recursion limit is reached.\nA minimum stacksize of 2400\ |
---|
| 33 | kbytes is recommended.\nSkipping infinite recursion test." |
---|
| 34 | testConstraint minStack2400 0 |
---|
| 35 | } |
---|
| 36 | } |
---|
| 37 | |
---|
| 38 | # |
---|
| 39 | # Custom match to detect a stack overflow independently of the mechanism that |
---|
| 40 | # triggered the error. |
---|
| 41 | # |
---|
| 42 | |
---|
| 43 | customMatch stackOverflow StackOverflow |
---|
| 44 | proc StackOverflow {- res} { |
---|
| 45 | set msgList [list \ |
---|
| 46 | "too many nested evaluations (infinite loop?)"\ |
---|
| 47 | "out of stack space (infinite loop?)"] |
---|
| 48 | expr {$res in $msgList} |
---|
| 49 | } |
---|
| 50 | |
---|
| 51 | test stack-1.1 {maxNestingDepth reached on infinite recursion} -constraints { |
---|
| 52 | minStack2400 |
---|
| 53 | } -body { |
---|
| 54 | # do this in a sub process in case it segfaults |
---|
| 55 | exec [interpreter] << { |
---|
| 56 | proc recurse {} { recurse } |
---|
| 57 | catch { recurse } rv |
---|
| 58 | puts $rv |
---|
| 59 | } |
---|
| 60 | } -match stackOverflow |
---|
| 61 | |
---|
| 62 | test stack-2.1 {maxNestingDepth reached on infinite recursion} -constraints { |
---|
| 63 | minStack2400 |
---|
| 64 | } -body { |
---|
| 65 | # do this in a sub process in case it segfaults |
---|
| 66 | exec [interpreter] << { |
---|
| 67 | interp alias {} unknown {} notaknownproc |
---|
| 68 | catch { unknown } msg |
---|
| 69 | puts $msg |
---|
| 70 | } |
---|
| 71 | } -match stackOverflow |
---|
| 72 | |
---|
| 73 | # Make sure that there is enough stack to run regexp even if we're |
---|
| 74 | # close to the recursion limit. [Bug 947070] [Patch 746378] |
---|
| 75 | test stack-3.1 {enough room for regexp near recursion limit} -body { |
---|
| 76 | # do this in a sub process in case it segfaults |
---|
| 77 | exec [interpreter] << { |
---|
| 78 | interp recursionlimit {} 10000 |
---|
| 79 | set depth 0 |
---|
| 80 | proc a { max } { |
---|
| 81 | if { [info level] < $max } { |
---|
| 82 | set ::depth [info level] |
---|
| 83 | a $max |
---|
| 84 | } else { |
---|
| 85 | regexp {^ ?} x |
---|
| 86 | } |
---|
| 87 | } |
---|
| 88 | catch { a 10001 } |
---|
| 89 | set depth2 $depth |
---|
| 90 | puts [list [a $depth] [expr { $depth2 - $depth }]] |
---|
| 91 | } |
---|
| 92 | } -result {1 1} |
---|
| 93 | |
---|
| 94 | # cleanup |
---|
| 95 | ::tcltest::cleanupTests |
---|
| 96 | return |
---|
| 97 | |
---|
| 98 | # Local Variables: |
---|
| 99 | # mode: tcl |
---|
| 100 | # End: |
---|