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:


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
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:
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)

    let main args =
        f 2500000 id |> ignore

Resulted in:
Stack overflow: IP: 0x40455ee2, fault addr: 0x7ffcdf437ff8
  at TestProgram.Test.f (int,Microsoft.FSharp.Core.FSharpFunc`2<int, int>)
  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 Wed Jun 24 10:04:37 UTC
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors.
    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
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.



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