Pergunta

When I run the following code:

(defun countdown (n)
  (if (>= n 0)
    (cons n (countdown (- n 1)))))

(countdown 100000)

I get the following message :

INFO: Control stack guard page unprotected
Control stack guard page temporarily disabled: proceed with caution

debugger invoked on a SB-KERNEL::CONTROL-STACK-EXHAUSTED in thread
#<THREAD "main thread" RUNNING {1002B03653}>:
  Control stack exhausted (no more space for function call frames).
This is probably due to heavily nested or infinitely recursive function
calls, or a tail call that SBCL cannot or has not optimized away.

PROCEED WITH CAUTION.

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

(SB-KERNEL::CONTROL-STACK-EXHAUSTED-ERROR)

How do I increase the stack space? I do not want to change the code above; I supplied it purely to illustrate stack exhaustion.

Foi útil?

Solução

Calling sbcl with the --help option on the command line gives some useful common options, including an option for how to increase the stack space. You want to to use the --control-stack-size argument.

$ sbcl --help
Usage: sbcl [runtime-options] [toplevel-options] [user-options]
Common runtime options:
  --help                     Print this message and exit.
  --version                  Print version information and exit.
  --core <filename>          Use the specified core file instead of the default.
  --dynamic-space-size <MiB> Size of reserved dynamic space in megabytes.
  --control-stack-size <MiB> Size of reserved control stack in megabytes.
...

By specifying a bigger value there, we can run your code:

$ sbcl --control-stack-size 100000
* (defun countdown (n)
  (if (>= n 0)
    (cons n (countdown (- n 1)))))
;=> (100000 … 6 5 4 3 2 1 0)

Outras dicas

Not exactly in time for the question at hand, but for anyone also wondering about the --control-stack-size:

From the SBCL manual section "3.3.1 Runtime Options" the default value for the --control-stack-size is 2 megabytes.

So for a list containing 100k 64bit-integers 7 megabyte sbcl --control-stack-size 7 should be sufficient!

As a reference:

CL-USER> (type-of 42)
(INTEGER 0 4611686018427387903)
CL-USER> (/ (* 64 100e3) (expt 2 20))
6.1035156
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top