<p dir="auto">This issue summarises the behaviour of julia when exposed to circular includes.<br>
The observed behaviour varies between julia versions from segfaults, irresponsive REPL or execution to rather intractable error messages.</p>
<p dir="auto">Even though circular includes are without a doubt a sign of bad code design, I'd find it desirable to see a more helpful error message and to avoid julia to run into a stack overflow or become irresponsive <g-emoji class="g-emoji" alias="smile" fallback-src="https://github.githubassets.com/images/icons/emoji/unicode/1f604.png">😄</g-emoji>.</p>
<h2 dir="auto">To reproduce</h2>
<ul dir="auto">
<li>File <code class="notranslate">a.jl</code>:</li>
</ul>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="include(&quot;b.jl&quot;)"><pre class="notranslate"><span class="pl-c1">include</span>(<span class="pl-s"><span class="pl-pds">"</span>b.jl<span class="pl-pds">"</span></span>)</pre></div>
<ul dir="auto">
<li>File <code class="notranslate">b.jl</code>:</li>
</ul>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="include(&quot;a.jl&quot;)"><pre class="notranslate"><span class="pl-c1">include</span>(<span class="pl-s"><span class="pl-pds">"</span>a.jl<span class="pl-pds">"</span></span>)</pre></div>
<h2 dir="auto">Test cases</h2>
<ul dir="auto">
<li><strong>REPL</strong>: A plain <code class="notranslate">julia&gt; include("a.jl")</code> was issued inside the REPL.</li>
<li><strong>script</strong>: I executed from a shell <code class="notranslate">julia a.jl</code>.</li>
</ul>
<h2 dir="auto">Result summary</h2>
<table role="table">
<thead>
<tr>
<th>julia version</th>
<th>REPL</th>
<th>script</th>
</tr>
</thead>
<tbody>
<tr>
<td>1.1</td>
<td>segfault</td>
<td>lengthy StackOverflowError</td>
</tr>
<tr>
<td>1.2</td>
<td>lengthy StackOverflowError + irresponsive</td>
<td>irresponsive</td>
</tr>
<tr>
<td>1.3</td>
<td>lengthy StackOverflowError + irresponsive</td>
<td>irresponsive</td>
</tr>
</tbody>
</table>
<p dir="auto">The behaviour changes between 1.1 and 1.2. The 1.2+ REPL behaviour is to print the error message</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="LoadError: LoadError: LoadError: LoadError: LoadError: LoadError:

... (many more times and finally) ...

StackOverflowError:"><pre class="notranslate"><code class="notranslate">LoadError: LoadError: LoadError: LoadError: LoadError: LoadError:

... (many more times and finally) ...

StackOverflowError:
</code></pre></div>
<p dir="auto">followed by an irresponsive REPL. When run as a script on 1.2+ the only printed output is</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ERROR: "><pre class="notranslate"><code class="notranslate">ERROR: 
</code></pre></div>
<p dir="auto">followed by an irresponsive julia process.</p>
<p dir="auto"><strong>Update:</strong> In fact "irresponsive" is not correct. The REPL/process just takes long (order of 2 minutes) to respond.</p>
<p dir="auto">This one is a bit tricky... (occurs on recent v0.5 builds from master, but not v0.4.6)</p>
<p dir="auto">If you have a specific sort of function containing a recursive call (like the one below), and <code class="notranslate">n</code> recursive calls leads to a Stack Overflow, then <em>sometimes</em> making <code class="notranslate">n-1</code> recursive calls leads to a Segmentation Fault.</p>
<p dir="auto">An example of such a function:</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="function f(x)
    if x &gt; 0
        unshift!(f(x-1), 1)
    else
        [1]
    end
end"><pre class="notranslate"><span class="pl-k">function</span> <span class="pl-en">f</span>(x)
    <span class="pl-k">if</span> x <span class="pl-k">&gt;</span> <span class="pl-c1">0</span>
        <span class="pl-c1">unshift!</span>(<span class="pl-c1">f</span>(x<span class="pl-k">-</span><span class="pl-c1">1</span>), <span class="pl-c1">1</span>)
    <span class="pl-k">else</span>
        [<span class="pl-c1">1</span>]
    <span class="pl-k">end</span>
<span class="pl-k">end</span></pre></div>
<p dir="auto">I've also created a little test file that does a simple binary search of the number of iterations to trigger the bug: <a href="https://gist.github.com/jballanc/1734f3a735b62c89908b51bb375d6c3e">https://gist.github.com/jballanc/1734f3a735b62c89908b51bb375d6c3e</a></p>
<p dir="auto">There seems to be a dependance on how the above script is run that affects whether or not the crash is triggered. On my machine running in the Emacs terminal crashes, running in a normal terminal doesn't crash, but running it as <code class="notranslate">julia -e 'versioninfo(); include("crash.jl")'</code> does crash. Manually searching for the correct <code class="notranslate">n</code> in the REPL also crashes reliably.</p>
<p dir="auto">The stack trace at the point of the segfault is:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="(lldb) bt
* thread #3: tid = 0xa312d, 0x0000000100139c10 libjulia.0.5.0.dylib`libunwind::LocalAddressSpace::get64(this=0x00000001002f2958, addr=140734791204856) + 16 at AddressSpace.hpp:92, stop reason = EXC_BAD_ACCESS (code=2, address=0x7fff5f3cbff8)
  * frame #0: 0x0000000100139c10 libjulia.0.5.0.dylib`libunwind::LocalAddressSpace::get64(this=0x00000001002f2958, addr=140734791204856) + 16 at AddressSpace.hpp:92
    frame #1: 0x000000010013e0fc libjulia.0.5.0.dylib`libunwind::CompactUnwinder_x86_64&lt;libunwind::LocalAddressSpace&gt;::stepWithCompactEncodingRBPFrame(compactEncoding=16974177, functionStart=4295582032, addressSpace=0x00000001002f2958, registers=0x0000700000103768) + 812 at CompactUnwinder.hpp:618
    frame #2: 0x000000010013dd58 libjulia.0.5.0.dylib`libunwind::CompactUnwinder_x86_64&lt;libunwind::LocalAddressSpace&gt;::stepWithCompactEncoding(compactEncoding=16974177, functionStart=4295582032, addressSpace=0x00000001002f2958, registers=0x0000700000103768) + 120 at CompactUnwinder.hpp:545
    frame #3: 0x000000010013dcd6 libjulia.0.5.0.dylib`libunwind::UnwindCursor&lt;libunwind::LocalAddressSpace, libunwind::Registers_x86_64&gt;::stepWithCompactEncoding(this=0x0000700000103710, (null)=0x00007000001034e0) + 54 at UnwindCursor.hpp:339
    frame #4: 0x000000010013b0ac libjulia.0.5.0.dylib`libunwind::UnwindCursor&lt;libunwind::LocalAddressSpace, libunwind::Registers_x86_64&gt;::stepWithCompactEncoding(this=0x0000700000103710) + 60 at UnwindCursor.hpp:337
    frame #5: 0x000000010013a4ea libjulia.0.5.0.dylib`libunwind::UnwindCursor&lt;libunwind::LocalAddressSpace, libunwind::Registers_x86_64&gt;::step(this=0x0000700000103710) + 90 at UnwindCursor.hpp:876
    frame #6: 0x00000001001397fe libjulia.0.5.0.dylib`::unw_step(cursor=0x0000700000103710) + 30 at libuwind.cxx:288
    frame #7: 0x0000000100090e19 libjulia.0.5.0.dylib`jl_unw_stepn [inlined] jl_unw_step(cursor=0x0000700000103710) + 441 at stackwalk.c:306 [opt]
    frame #8: 0x0000000100090dd7 libjulia.0.5.0.dylib`jl_unw_stepn(cursor=0x0000700000103710, ip=0x0000000103cb9000, sp=&lt;unavailable&gt;, maxsize=80000) + 375 at stackwalk.c:46 [opt]
    frame #9: 0x0000000100090ecf libjulia.0.5.0.dylib`rec_backtrace_ctx(data=0x0000000103cb9000, maxsize=80000, context=&lt;unavailable&gt;) + 63 at stackwalk.c:75 [opt]
    frame #10: 0x00000001000815fd libjulia.0.5.0.dylib`jl_throw_in_thread(tid=&lt;unavailable&gt;, thread=1295, exception=0x0000000105c49b38) + 109 at signals-mach.c:131 [opt]
    frame #11: 0x00000001000819b6 libjulia.0.5.0.dylib`catch_exception_raise(exception_port=&lt;unavailable&gt;, thread=1295, task=&lt;unavailable&gt;, exception=&lt;unavailable&gt;, code=&lt;unavailable&gt;, code_count=&lt;unavailable&gt;) + 822 at signals-mach.c:227 [opt]
    frame #12: 0x00007fff8bfac440 libsystem_kernel.dylib`_Xexception_raise + 130
    frame #13: 0x00007fff8bfac6fe libsystem_kernel.dylib`exc_server + 78
    frame #14: 0x00007fff8bfbbce0 libsystem_kernel.dylib`mach_msg_server + 504
    frame #15: 0x000000010008155d libjulia.0.5.0.dylib`mach_segv_listener(arg=&lt;unavailable&gt;) + 29 at signals-mach.c:73 [opt]
    frame #16: 0x00007fff8d37199d libsystem_pthread.dylib`_pthread_body + 131
    frame #17: 0x00007fff8d37191a libsystem_pthread.dylib`_pthread_start + 168
    frame #18: 0x00007fff8d36f351 libsystem_pthread.dylib`thread_start + 13"><pre class="notranslate"><code class="notranslate">(lldb) bt
* thread #3: tid = 0xa312d, 0x0000000100139c10 libjulia.0.5.0.dylib`libunwind::LocalAddressSpace::get64(this=0x00000001002f2958, addr=140734791204856) + 16 at AddressSpace.hpp:92, stop reason = EXC_BAD_ACCESS (code=2, address=0x7fff5f3cbff8)
  * frame #0: 0x0000000100139c10 libjulia.0.5.0.dylib`libunwind::LocalAddressSpace::get64(this=0x00000001002f2958, addr=140734791204856) + 16 at AddressSpace.hpp:92
    frame #1: 0x000000010013e0fc libjulia.0.5.0.dylib`libunwind::CompactUnwinder_x86_64&lt;libunwind::LocalAddressSpace&gt;::stepWithCompactEncodingRBPFrame(compactEncoding=16974177, functionStart=4295582032, addressSpace=0x00000001002f2958, registers=0x0000700000103768) + 812 at CompactUnwinder.hpp:618
    frame #2: 0x000000010013dd58 libjulia.0.5.0.dylib`libunwind::CompactUnwinder_x86_64&lt;libunwind::LocalAddressSpace&gt;::stepWithCompactEncoding(compactEncoding=16974177, functionStart=4295582032, addressSpace=0x00000001002f2958, registers=0x0000700000103768) + 120 at CompactUnwinder.hpp:545
    frame #3: 0x000000010013dcd6 libjulia.0.5.0.dylib`libunwind::UnwindCursor&lt;libunwind::LocalAddressSpace, libunwind::Registers_x86_64&gt;::stepWithCompactEncoding(this=0x0000700000103710, (null)=0x00007000001034e0) + 54 at UnwindCursor.hpp:339
    frame #4: 0x000000010013b0ac libjulia.0.5.0.dylib`libunwind::UnwindCursor&lt;libunwind::LocalAddressSpace, libunwind::Registers_x86_64&gt;::stepWithCompactEncoding(this=0x0000700000103710) + 60 at UnwindCursor.hpp:337
    frame #5: 0x000000010013a4ea libjulia.0.5.0.dylib`libunwind::UnwindCursor&lt;libunwind::LocalAddressSpace, libunwind::Registers_x86_64&gt;::step(this=0x0000700000103710) + 90 at UnwindCursor.hpp:876
    frame #6: 0x00000001001397fe libjulia.0.5.0.dylib`::unw_step(cursor=0x0000700000103710) + 30 at libuwind.cxx:288
    frame #7: 0x0000000100090e19 libjulia.0.5.0.dylib`jl_unw_stepn [inlined] jl_unw_step(cursor=0x0000700000103710) + 441 at stackwalk.c:306 [opt]
    frame #8: 0x0000000100090dd7 libjulia.0.5.0.dylib`jl_unw_stepn(cursor=0x0000700000103710, ip=0x0000000103cb9000, sp=&lt;unavailable&gt;, maxsize=80000) + 375 at stackwalk.c:46 [opt]
    frame #9: 0x0000000100090ecf libjulia.0.5.0.dylib`rec_backtrace_ctx(data=0x0000000103cb9000, maxsize=80000, context=&lt;unavailable&gt;) + 63 at stackwalk.c:75 [opt]
    frame #10: 0x00000001000815fd libjulia.0.5.0.dylib`jl_throw_in_thread(tid=&lt;unavailable&gt;, thread=1295, exception=0x0000000105c49b38) + 109 at signals-mach.c:131 [opt]
    frame #11: 0x00000001000819b6 libjulia.0.5.0.dylib`catch_exception_raise(exception_port=&lt;unavailable&gt;, thread=1295, task=&lt;unavailable&gt;, exception=&lt;unavailable&gt;, code=&lt;unavailable&gt;, code_count=&lt;unavailable&gt;) + 822 at signals-mach.c:227 [opt]
    frame #12: 0x00007fff8bfac440 libsystem_kernel.dylib`_Xexception_raise + 130
    frame #13: 0x00007fff8bfac6fe libsystem_kernel.dylib`exc_server + 78
    frame #14: 0x00007fff8bfbbce0 libsystem_kernel.dylib`mach_msg_server + 504
    frame #15: 0x000000010008155d libjulia.0.5.0.dylib`mach_segv_listener(arg=&lt;unavailable&gt;) + 29 at signals-mach.c:73 [opt]
    frame #16: 0x00007fff8d37199d libsystem_pthread.dylib`_pthread_body + 131
    frame #17: 0x00007fff8d37191a libsystem_pthread.dylib`_pthread_start + 168
    frame #18: 0x00007fff8d36f351 libsystem_pthread.dylib`thread_start + 13
</code></pre></div>