(reporting as an issue - suggested by John Colvin) I'm consistently getting "Segmentation fault: 11" (dmd 2.067.1, OSX) on the code below. I can't figure out where things are going wrong, because any attempt I make to debug via extra print statements causes the program to run successfully. Same if I try to compile with "-gc" ... it suddenly starts working, so I can't debug with gdb. And the code similarly seems to work fine with ldc2. Many thanks in advance! * * * import std.stdio; enum Suit { HEARTS, DIAMONDS, CLUBS, SPADES } enum Value { ACE = 1, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING } struct Card { Value value; Suit suit; } void printCard(in Card card) { final switch(card.value) { case Value.ACE: write("A"); break; case Value.TWO, Value.THREE, Value.FOUR, Value.FIVE, Value.SIX, Value.SEVEN, Value.EIGHT, Value.NINE, Value.TEN: writef("%d", card.value); break; case Value.JACK: write("J"); break; case Value.QUEEN: write("Q"); break; case Value.KING: write("K"); break; } final switch(card.suit) { case Suit.HEARTS: write("♡"); break; case Suit.DIAMONDS: write("♢"); break; case Suit.CLUBS: write("♣"); break; case Suit.SPADES: write("♠"); break; } write("\n"); } int main() { auto card = Card(Value.JACK, Suit.CLUBS); printCard(card); return 0; }
A reduced version: struct Card { int value; int suit; } void foo(Card card) { switch(card.value) { case 4: case 5: case 6: case 11: break; default: } } void main() { auto card = Card(11, 1); foo(card); } Changing anything at this point seems to make it run properly.
Thanks for reducing it Steven! I also did a bit more leg-work. It could be coincidence, but the code seems to work in DMD 2.063.2 and below and fails in 2.064 and above. Not only OSX. Linux (64-bit) at a minimum as well.
FWIW, I can reproduce it with DMD master on Linux x86_64. Interestingly, compiling with debug info makes the SEGV go away.
It crashes upon entering the jump table: (gdb) disas Dump of assembler code for function _D2xx3fooFS2xx4CardZv: 0x000000000041c7b0 <+0>: push %rbp 0x000000000041c7b1 <+1>: mov %rsp,%rbp 0x000000000041c7b4 <+4>: sub $0x10,%rsp 0x000000000041c7b8 <+8>: mov %rdi,-0x8(%rbp) 0x000000000041c7bc <+12>: cmp $0xb,%edi 0x000000000041c7bf <+15>: ja 0x41c7c8 <_D2xx3fooFS2xx4CardZv+24> => 0x000000000041c7c1 <+17>: jmpq *0x4374f8(,%rdi,8) 0x000000000041c7c8 <+24>: leaveq 0x000000000041c7c9 <+25>: retq (gdb) print $edi $1 = 11 (gdb) print $rdi $2 = 4294967307 As you can see, %edi contains the correct offset, but it uses %rdi as an index. Most likely a bug in the code generator.
Introduced in https://github.com/D-Programming-Language/dmd/pull/2315
Great job, everyone, in tracking this one down. You guys have nailed it. It's critical. I'll work on a fix.
https://github.com/D-Programming-Language/dmd/pull/4666
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/4f779561f89e12ff45e30996ad3c8217eb7522e2 fix Issue 14587 - DMD 2.067.1 generating crashing binary on OSX https://github.com/D-Programming-Language/dmd/commit/a7d1edb3c17282994c53fdc797dc3d15f3919d68 Merge pull request #4666 from WalterBright/fix14587 fix Issue 14587 - generated 64 bit code for switch jump tables is wrong
Commit pushed to dmd-1.x at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/51185a88a63762c5347b729e26ab9540c34201da Merge pull request #4666 from WalterBright/fix14587 fix Issue 14587 - generated 64 bit code for switch jump tables is wrong
Awesome! Nice work everyone.
Wow ... that was a productive weekend! Looking forward to this working its way into a future homebrew update! :D
Commits pushed to stable at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/4f779561f89e12ff45e30996ad3c8217eb7522e2 fix Issue 14587 - DMD 2.067.1 generating crashing binary on OSX https://github.com/D-Programming-Language/dmd/commit/a7d1edb3c17282994c53fdc797dc3d15f3919d68 Merge pull request #4666 from WalterBright/fix14587