This is Xamarin's bug tracking system. For product support, please use the support links listed in your Xamarin Account.
Bug 12635 - Tail calls inside continuations cause StackOverflow
: Tail calls inside continuations cause StackOverflow
Status: NEW
Product: Runtime
Classification: Mono
Component: JIT
: unspecified
: PC Mac OS
: Normal normal
: ---
Assigned To: Bugzilla
:
:
:
  Show dependency treegraph
 
Reported: 2013-06-11 13:49 EDT by Natallie
Modified: 2015-08-14 23:52 EDT (History)
8 users (show)

See Also:
Tags:


Attachments

Description Natallie 2013-06-11 13:49:31 EDT
The following sample program fails with StackOverflow:

let rec f x cont =
    if x < 0 then 0
    elif x = 0 then cont x
    else f (x-1) (fun x -> f x cont)

f 250000 id

Rewriting the functions so that they all have a single parameter doesn't help
here.
Comment 1 Alexander Kyte 2015-03-29 13:19:58 EDT
Using mono 3.12.1, this doesn't stack overflow for me. You might be using an
older mono.
Comment 2 Natallie 2015-03-30 16:36:03 EDT
Yes, that was 2 years ago. However, it still doesn't work for me:
http://cl.ly/image/0T2U213d0p04
Comment 3 Andrew Browne 2015-08-12 06:33:57 EDT
I can confirm this is still happening in current versions of mono. Although I
had to add a zero:

namespace TestProgram

module Test =
    let rec f x cont =
        if x < 0 then 0
        elif x = 0 then cont x
        else f (x-1) (fun x -> f x cont)

    [<EntryPoint>]
    let main args =
        f 2500000 id |> ignore
        0

Resulted in:
Stack overflow: IP: 0x40455ee2, fault addr: 0x7ffcdf437ff8
Stacktrace:
  at TestProgram.Test.f (int,Microsoft.FSharp.Core.FSharpFunc`2<int, int>)
<0x00034>
  <...>
  at TestProgram.Test.main (string[]) <0x00027>
  at (wrapper runtime-invoke) <Module>.runtime_invoke_int_object
(object,intptr,intptr,intptr) <0xffffffff>

My mono version:
mono --version
Mono JIT compiler version 4.0.2 (Stable 4.0.2.5/c99aa0c Wed Jun 24 10:04:37 UTC
2015)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors.
www.mono-project.com
    TLS:           __thread
    SIGSEGV:       altstack
    Notifications: epoll
    Architecture:  amd64
    Disabled:      none
    Misc:          softdebug 
    LLVM:          supported, not enabled.
    GC:            sgen
Comment 4 Andrew Browne 2015-08-12 18:31:17 EDT
After reviewing the code again I don't think this code is tail recursive. The f
x cont case is not in tail position.
Comment 5 Andrew Browne 2015-08-12 18:31:45 EDT
I have also confirmed that this sample code crashes under the Microsoft CLR as
well.
Comment 6 Natallie 2015-08-14 16:10:55 EDT
@Andrew: make sure you compile the code with tail calls enabled, then you can
verify that the .tail instruction is there. I don't have a windows machine
around to check, but it used to work with .NET framework.
Comment 7 Andrew Browne 2015-08-14 23:52:49 EDT
@Natallie. Sorry tried again on a different machine and couldn't get it to
fail. So it looks like it does work on Microsoft CLR. When I'm back at work
next week I'll try and replicate the failure again but maybe I did have tail
calls off.

c:\temp>fsc Test.fs
Microsoft (R) F# Compiler version 12.0.30815.0
Copyright (c) Microsoft Corporation. All Rights Reserved.

c:\temp>Test.exe

c:\temp>

Note You need to log in before you can comment on or make changes to this bug.