digitalmars.D.bugs - [Issue 16274] New: The curses of debugging: short argument passed in
- via Digitalmars-d-bugs (125/125) Jul 12 2016 https://issues.dlang.org/show_bug.cgi?id=16274
https://issues.dlang.org/show_bug.cgi?id=16274 Issue ID: 16274 Summary: The curses of debugging: short argument passed in 16-bit register, against ABI Product: D Version: D2 Hardware: x86 OS: Mac OS X Status: NEW Severity: enhancement Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: luis luismarques.eu On my system (OS X 10.11.5 (15F34), 64-bit), if you compile (with DMD) and run the following program you'll get an executable that behaves incorrectly about half of the executions: extern(C) { void* initscr(); int start_color(); int init_pair(short pair, short f, short b); int attron(int attrs); int mvprintw(int y, int x, const(char)* fmt, ...); int attroff(int attrs); int getch(); int endwin(); int refresh(); } enum { COLOR_BLACK = 0, COLOR_RED = 1, COLOR_GREEN = 2, COLOR_YELLOW = 3, COLOR_BLUE = 4, COLOR_MAGENTA = 5, COLOR_CYAN = 6, COLOR_WHITE = 7 } int COLOR_PAIR(int n) { return n << 8; } void main() { initscr(); start_color(); init_pair(1, COLOR_WHITE, COLOR_BLUE); int pair = COLOR_PAIR(1); attron(pair); mvprintw(1, 1, "Test"); attroff(pair); refresh(); getch(); endwin(); } $ rdmd -L-lcurses test.d If all is well, you'll see the text "Test" in white text on a blue background. If the bug is exercised then you won't see any text. Sometimes it takes quite a few number of executions until it starts or stops exhibiting the problem. This reduced text case was taken very painstakingly from a large codebase, where changing unrelated things around would make the problem come and go --- probably; it was sometimes hard to tell, given the non-deterministic bug. Currently, it seems that this program always works fine when using LDC, although my vague recollection is that this wasn't true when I had last looked at this issue (which was before the latest LDC). That might be because of the following difference in compilation: LDC: __Dmain: subq $0x38, %rsp callq _initscr movq %rax, 0x28(%rsp) callq _start_color movl $0x1, %edi <--- movl $0x7, %esi <--- movl $0x4, %edx <--- movl %eax, 0x24(%rsp) callq _init_pair DMD: __Dmain: pushq %rbp movq %rsp, %rbp subq $0x10, %rsp callq _initscr callq _start_color movw $0x4, %dx <--- movw $0x7, %si <--- movw $0x1, %di <--- callq _init_pair And indeed, if you change the code to the following the problem goes away: void main() { initscr(); start_color(); asm { xor EDX, EDX; xor ESI, ESI; xor EDI, EDI; } init_pair(1, COLOR_WHITE, COLOR_BLUE); int pair = COLOR_PAIR(1); attron(pair); mvprintw(1, 1, "Test"); attroff(pair); refresh(); getch(); endwin(); } I guess the ABI requires the whole register to be used for a 16-bit value? The docs for my system say "The OS X x86-64 function calling conventions are the same as the function calling conventions described in System V Application Binary Interface AMD64 Architecture Processor Supplement, found at http://people.freebsd.org/~obrien/amd64-elf-abi.pdf. See that document for details." In that document I found the following: • Arguments of types (signed and unsigned) _Bool, char, short, int, long, long long, and pointers are in the INTEGER class (...) 2. If the class is INTEGER, the next available register of the sequence %rdi, %rsi, %rdx, %rcx, %r8 and %r9 is used So I guess this is a DMD code generation bug? --
Jul 12 2016