Tricky DMD bug, but I have no idea how to report

H. S. Teoh hsteoh at quickfur.ath.cx
Mon Dec 17 22:22:05 UTC 2018


On Mon, Dec 17, 2018 at 09:59:59PM +0000, JN via Digitalmars-d-learn wrote:
[...]
> class Texture2D {}
> 
> auto a = new Texture2D();
> auto b = new Texture2D();
> auto c = new Texture2D();
> Texture2D[int] TextureBindings;
> writeln(a, b, c);
> textureBindings[0] = a;
> textureBindings[1] = b;
> textureBindings[2] = c;
> writeln(textureBindings);
> 
> and the output is:
> 
> Texture2DTexture2DTexture2D
> [0:null, 2:null, 1:null]
> 
> I'd expect it to output:
> 
> Texture2DTexture2DTexture2D
> [0:Texture2D, 2:Texture2D, 1:Texture2D]
> 
> depending on what I change around this code, for example changing it to
> 
> writeln(a, " ", b, " ", c);
> 
> results in output of:
> 
> Texture2D Texture2D Texture2D
> [0:Texture2D, 2:null, 1:null]

Ah, a pointer bug.  Lovely. :-/

My first guess is that you have a bunch of references to local variables
that have gone out of scope.


> It feels completely random. Removing, adding calls completely
> unrelated to these changes the result.

Typical symptoms of a pointer bug of some kind.  Could be an
uninitialized pointer, if you have used `T* p = void;` anywhere.


> My guess is that the compiler somehow reorders the calls incorrectly,
> changing the semantics.

Possible, but unlikely.  My bet is that you have dangling pointers, most
likely to local variables that have gone out of scope.  Perhaps
somewhere in the code you ran into the evil implicit conversion of
static arrays into slices, which results in dangling pointers if said
slice persists beyond the lifetime of the static array.

Another likely candidate is that if you're calling C/C++ libraries
somewhere in your code, you may have passed in a wrong size, perhaps a
byte count where an array length ought to be used, or vice versa, and as
a result you got a buffer overrun.  I ran into similar bugs when writing
OpenGL code.


> Trick is, LDC works correctly and produces the expected result, both
> when compiling in debug and release mode.
[...]

I bet the bug is still there, just latent because of the slightly
different memory layout when compiling with LDC.  You probably want to
be absolutely sure it's a compiler bug before moving on, as it could
very well be a bug in your code.

A less likely possibility might be an optimizer bug -- do you get
different results if you add / remove '-O' (and/or '-inline') from your
dmd command-line?  If some combination of -O and -inline (or their
removal thereof) "fixes" the problem, it could be an optimizer bug. But
those are rare, and usually only show up when you use an obscure D
feature combined with another obscure corner case, in a way that people
haven't thought of.  My bet is still on a pointer bug somewhere in your
code.


T

-- 
If the comments and the code disagree, it's likely that *both* are wrong. -- Christopher


More information about the Digitalmars-d-learn mailing list