www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 18026] New: Stack overflow in ddmd/dtemplate.d:6241,


          Issue ID: 18026
           Summary: Stack overflow in ddmd/dtemplate.d:6241,
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: zorael gmail.com

Arch/Manjaro 64-bit, dmd v2.077.0 and ldc 1.6.0 (2.076.1) from official
repositories. Tested on two machines with similar setups. Could not reproduce
in Windows (32-bit), and I didn't seem to have the libraries for 32-bit linux
builds so could not test that.

I've run into this on more than once now. In cases that are difficult to
isolate and reason about, dmd and ldc will both fail to compile with dub -b
plain and dub -b release, exiting with code -11. -b debug and -b unittest work
fine. Things like in what order files are specified when compiling matters.
I've even managed to get it to a point where it builds sometimes (!) and other
times errors out.

 zorael xps ~/src/kameloso [overflow] $ dub build -b plain --force
 Performing "plain" build using dmd for x86_64.
 kameloso ~overflow: building configuration "application"...
 zorael xps ~/src/kameloso [overflow] $ dub build -b plain --force
 Performing "plain" build using dmd for x86_64.
 kameloso ~overflow: building configuration "application"...
 dmd failed with exit code -11.
In https://forum.dlang.org/post/peaywtdvlrohnohjxlcc forum.dlang.org I managed to find one line to change that fixed one issue (replaced size_t with uint). I now ran into a different case where it breaks if I remove a particular function call line in a function. I wanted to move it to a different module, so what I end up having to do is renaming the original function and keeping it with just that one critical line in it.
 void removeMeWhenPossible()
     import kameloso.debugging : formatEventAssertBlock;
     import std.array : Appender;
     Appender!(char[]) sink;
     sink.formatEventAssertBlock(IRCEvent.init);  // <-- stack overflow without
this line
As mentioned on the forum page with the issue there, gdb on a debug dmd showed a stack overflow in TemplateInstance::needsCodegen().
 6233|             // Determine necessity of tinst before tnext.
 6234|             if (tinst && tinst.needsCodegen())
 6235|             {
 6236|                 minst = tinst.minst; // cache result
 6237|                 assert(minst);
 6238|                 assert(minst.isRoot() || minst.rootImports());
 6239|                 return true;
 6240|             }
 6241|---------->  if (tnext && (tnext.needsCodegen() || tnext.minst))
 6242|             {
 6243|                 minst = tnext.minst; // cache result
 6244|                 assert(minst);
 6245|                 return minst.isRoot() || minst.rootImports(); 6246
The ldc output seems to agree;
I managed to produce a smaller test case by just gutting my project and seeing how small I could get a broken sample. There were a lot of places where commenting something out fixed it. It still weighs in at just less than 1k sloc (ignoring arsd modules) and it's full of stubs and noops, but it's easy to compile.
 $ git clone -b overflow https://github.com/zorael/kameloso.git
The latest commit in that overflow branch (00f375) builds *sometimes*, while the commit previous to it (546cea or HEAD~) reliably fails every time. I stopped trying to reduce there. I'm not sure if any of this helps, but Petar Kirov [ZombineDev] suggested I report it in either case. --
Dec 03 2017