[Issue 18026] New: Stack overflow in ddmd/dtemplate.d:6241, TemplateInstance::needsCodegen()

d-bugmail at puremagic.com d-bugmail at puremagic.com
Sun Dec 3 16:01:31 UTC 2017


https://issues.dlang.org/show_bug.cgi?id=18026

          Issue ID: 18026
           Summary: Stack overflow in ddmd/dtemplate.d:6241,
                    TemplateInstance::needsCodegen()
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody at puremagic.com
          Reporter: zorael at 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 at xps ~/src/kameloso [overflow] $ dub build -b plain --force
> Performing "plain" build using dmd for x86_64.
> kameloso ~overflow: building configuration "application"...
> Linking...
> 
> zorael at 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
>     assert(0);
> }

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;

> /usr/lib/libLLVM-5.0.so(_ZN4llvm3sys15PrintStackTraceERNS_11raw_ostreamE+0x2b)[0x7fd8b08329bb]
> /usr/lib/libLLVM-5.0.so(_ZN4llvm3sys17RunSignalHandlersEv+0x56)[0x7fd8b0830806]
> /usr/lib/libLLVM-5.0.so(+0x808953)[0x7fd8b0830953]
> /usr/lib/libpthread.so.0(+0x11da0)[0x7fd8afe1bda0]
> ldc(_ZN16TemplateInstance12needsCodegenEv+0xfe)[0x56173bcef2c2]
> ldc(_ZN16TemplateInstance12needsCodegenEv+0x103)[0x56173bcef2c7]
> ldc(_ZN16TemplateInstance12needsCodegenEv+0x103)[0x56173bcef2c7]
> ldc(_ZN16TemplateInstance12needsCodegenEv+0x103)[0x56173bcef2c7]
> ldc(_ZN16TemplateInstance12needsCodegenEv+0x103)[0x56173bcef2c7]
> [...]

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.

--


More information about the Digitalmars-d-bugs mailing list