Subject: bug#24005: closed (Re: bug#24005: Segfault after playing around a bit)

From: [email-masked] (GNU bug Tracking System)
Date: Sat, 23 Jul 2016 10:46:02 +0000

Your bug report

#24005: Segfault after playing around a bit

which was filed against the guile package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
24005: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=24005
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#24005: Segfault after playing around a bit
From: Andy Wingo <[email-masked]>
To: Giedrius Statkevičius <[email-masked]>
Cc: [email-masked]
Date: Sat, 23 Jul 2016 12:45:05 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi :)

On Sat 16 Jul 2016 13:46, Giedrius Statkevičius <[email-masked]> writes:

> scheme@(guile-user)> (define (sqrt-iter guess x) (new-if (good-enough? guess x)
> guess (sqrt-iter (improve guess x) x)))
> scheme@(guile-user)> (sqrt 2)
> <unnamed port>:4:42: In procedure good-enough?:
> <unnamed port>:4:42: Throw to key `vm-error' with args `(vm-run "VM: Stack

What's happening here is that you have a function that uses too much
stack.  In Guile 2.0 there is a fixed amount of stack.  If you exceed
that amount, Guile enters a nested REPL at the error:

> Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
> scheme@(guile-user) [1]> (define (sqrt-iter guess x) (new-if (good-enough? guess
> x) guess x))

So you can get a backtrace to see what's on your stack.  This repl is in
the context of the stack overflow -- so all the frames are still on the
stack.  There's just a little bit of stack reserved so that you can poke
around and see what's going on.  You then cause the stack overflow
again, when it already overflowed, and at some point Guile detects this
and because it can't handle it, it aborts (not segfaults):

> zsh: abort (core dumped)  guile

Ah well.  In Guile 2.0 we can't fix this very nicely.  There's no
corruption here, just a limit that we can't handle.  Fortunately we
fixed it in 2.2:

  https://wingolog.org/archives/2014/03/17/stack-overflow

My machine is down for maintenance atm, should be back shortly, in the
meantime there's

  https://web.archive.org/web/*/https://wingolog.org/archives/2014/03/17/stack-overflow

Anyway.  Thanks for the report, it's a limitation in 2.0 that's fixed in
2.2.

Cheers,

Andy

Subject: Segfault after playing around a bit
From: Giedrius Statkevičius <[email-masked]>
To: [email-masked]
Date: Sat, 16 Jul 2016 14:46:36 +0300
List-Id: <debbugs-submit.debbugs.gnu.org>

Basically I've been playing around with guile and trying to do a SICP
exercise:

diablo@tyrael:~/ > guile
GNU Guile 2.0.11
Copyright (C) 1995-2014 Free Software Foundation, Inc.

Guile comes with ABSOLUTELY NO WARRANTY; for details type `,show w'.
This program is free software, and you are welcome to redistribute it
under certain conditions; type `,show c' for details.

Enter `,help' for help.
scheme@(guile-user)> (define (improve guess x) (average guess (/ x guess)))
;;; <stdin>:1:26: warning: possibly unbound variable `average'
scheme@(guile-user)> (define (average x y) (/ (+ x y) 2))
scheme@(guile-user)> (define (improve guess x) (average guess (/ x guess)))
scheme@(guile-user)> (define (good-enough? guess x) (< (abs (- (square guess)
x)) 0.001))
;;; <stdin>:4:42: warning: possibly unbound variable `square'
scheme@(guile-user)> (define (sqrt x) (sqrt-iter 1.0 x))
;;; <stdin>:5:17: warning: possibly unbound variable `sqrt-iter'
scheme@(guile-user)> (define (square x) (* x x))
scheme@(guile-user)> (define (sqrt-iter guess x) (if (good-enough? guess x)
guess (sqrt-iter (improve guess x) x)))
scheme@(guile-user)> (sqrt 2)
$1 = 1.4142156862745097
scheme@(guile-user)> (sqrt 9)
$2 = 3.00009155413138
scheme@(guile-user)> (define (new-if predicate then-clause else-clause) (cond
(predicate then-clause)
(else else-clause)))
scheme@(guile-user)> (new-if (> 2 1) (sqrt 2) (sqrt 3))
$3 = 1.4142156862745097
scheme@(guile-user)> (define (sqrt-iter guess x) (new-if (good-enough? guess x)
guess (sqrt-iter (improve guess x) x)))
scheme@(guile-user)> (sqrt 2)
<unnamed port>:4:42: In procedure good-enough?:
<unnamed port>:4:42: Throw to key `vm-error' with args `(vm-run "VM: Stack
overflow" ())'.

Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
scheme@(guile-user) [1]> (define (sqrt-iter guess x) (new-if (good-enough? guess
x) guess x))
zsh: abort (core dumped)  guile

Stack traces:
                Stack trace of thread 31457:
                #0  0x00007f13299c0295 raise (libc.so.6)
                #1  0x00007f13299c16da abort (libc.so.6)
                #2  0x00007f132a02b128 n/a (libguile-2.0.so.22)
                #3  0x00007f132a02c0dd n/a (libguile-2.0.so.22)
                #4  0x00007f132a042968 scm_call_with_vm (libguile-2.0.so.22)
                #5  0x00007f132a02a9bb n/a (libguile-2.0.so.22)
                #6  0x00007f132a02b123 n/a (libguile-2.0.so.22)
                #7  0x00007f132a02c0dd n/a (libguile-2.0.so.22)
                #8  0x00007f1329faf023 scm_primitive_eval (libguile-2.0.so.22)
                #9  0x00007f1329faf083 scm_eval (libguile-2.0.so.22)
                #10 0x00007f132a0032c0 scm_shell (libguile-2.0.so.22)
                #11 0x00007f1329fcc3dd n/a (libguile-2.0.so.22)
                #12 0x00007f1329fa4caa n/a (libguile-2.0.so.22)
                #13 0x00007f132a0423b2 n/a (libguile-2.0.so.22)
                #14 0x00007f1329faea73 scm_call_4 (libguile-2.0.so.22)
                #15 0x00007f1329fa5451 n/a (libguile-2.0.so.22)
                #16 0x00007f1329fa5535 scm_c_with_continuation_barrier (libguile-2.0.so.22)
                #17 0x00007f132a0251dc n/a (libguile-2.0.so.22)
                #18 0x00007f1329738832 GC_call_with_stack_base (libgc.so.1)
                #19 0x00007f132a025608 scm_with_guile (libguile-2.0.so.22)
                #20 0x00007f1329fcc5b5 scm_boot_guile (libguile-2.0.so.22)
                #21 0x0000000000400c20 n/a (guile)
                #22 0x00007f13299ad741 __libc_start_main (libc.so.6)
                #23 0x0000000000400ca9 n/a (guile)

                Stack trace of thread 31461:
                #0  0x00007f1329d3e16d read (libpthread.so.0)
                #1  0x00007f132a001ea7 n/a (libguile-2.0.so.22)
                #2  0x00007f132973e7e2 n/a (libgc.so.1)
                #3  0x00007f13297329cf n/a (libgc.so.1)
                #4  0x00007f132973888c GC_do_blocking (libgc.so.1)
                #5  0x00007f132a02569a scm_without_guile (libguile-2.0.so.22)
                #6  0x00007f132a001df3 n/a (libguile-2.0.so.22)
                #7  0x00007f132a03880e n/a (libguile-2.0.so.22)
                #8  0x00007f1329faea0e scm_call_3 (libguile-2.0.so.22)
                #9  0x00007f132a027bfe scm_internal_catch (libguile-2.0.so.22)
                #10 0x00007f132a025b3c n/a (libguile-2.0.so.22)
                #11 0x00007f1329fa4caa n/a (libguile-2.0.so.22)
                #12 0x00007f132a03880e n/a (libguile-2.0.so.22)
                #13 0x00007f1329faea73 scm_call_4 (libguile-2.0.so.22)
                #14 0x00007f1329fa5451 n/a (libguile-2.0.so.22)
                #15 0x00007f1329fa5535 scm_c_with_continuation_barrier (libguile-2.0.so.22)
                #16 0x00007f132a0251dc n/a (libguile-2.0.so.22)
                #17 0x00007f1329738832 GC_call_with_stack_base (libgc.so.1)
                #18 0x00007f132a024bdc n/a (libguile-2.0.so.22)
                #19 0x00007f132973d976 n/a (libgc.so.1)
                #20 0x00007f1329738832 GC_call_with_stack_base (libgc.so.1)
                #21 0x00007f1329d35484 start_thread (libpthread.so.0)
                #22 0x00007f1329a746dd __clone (libc.so.6)

                Stack trace of thread 31458:
                #0  0x00007f1329d3b0af pthread_cond_wait@@GLIBC_2.3.2 (libpthread.so.0)
                #1  0x00007f132973f867 n/a (libgc.so.1)
                #2  0x00007f132973570a n/a (libgc.so.1)
                #3  0x00007f132973da5f n/a (libgc.so.1)
                #4  0x00007f1329d35484 start_thread (libpthread.so.0)
                #5  0x00007f1329a746dd __clone (libc.so.6)

                Stack trace of thread 31459:
                #0  0x00007f1329d3b0af pthread_cond_wait@@GLIBC_2.3.2 (libpthread.so.0)
                #1  0x00007f132973f867 n/a (libgc.so.1)
                #2  0x00007f132973570a n/a (libgc.so.1)
                #3  0x00007f132973da5f n/a (libgc.so.1)
                #4  0x00007f1329d35484 start_thread (libpthread.so.0)
                #5  0x00007f1329a746dd __clone (libc.so.6)

                Stack trace of thread 31460:
                #0  0x00007f1329d3b0af pthread_cond_wait@@GLIBC_2.3.2 (libpthread.so.0)
                #1  0x00007f132973f867 n/a (libgc.so.1)
                #2  0x00007f132973570a n/a (libgc.so.1)
                #3  0x00007f132973da5f n/a (libgc.so.1)
                #4  0x00007f1329d35484 start_thread (libpthread.so.0)
                #5  0x00007f1329a746dd __clone (libc.so.6)

So it seems to me like guile doesn't handle stack overflows gracefully and just
crashes but I'm not sure.

diablo@tyrael:~/ > guile --version
guile (GNU Guile) 2.0.11
Copyright (C) 2014 Free Software Foundation, Inc.

License LGPLv3+: GNU LGPL 3 or later <http://gnu.org/licenses/lgpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

-- 
        Giedrius