(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;
}
Comment #1 by schveiguy — 2015-05-15T13:49:31Z
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.
Comment #2 by robpieke — 2015-05-15T16:14:32Z
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.
Comment #3 by schuetzm — 2015-05-15T16:25:53Z
FWIW, I can reproduce it with DMD master on Linux x86_64. Interestingly, compiling with debug info makes the SEGV go away.
Comment #4 by schuetzm — 2015-05-15T16:36:06Z
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.
Comment #5 by dlang-bugzilla — 2015-05-17T05:42:26Z