www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 10723] New: std.stdio.File.byLine causes segfault when compiling with -O

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10723

           Summary: std.stdio.File.byLine causes segfault when compiling
                    with -O
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: major
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: hsteoh quickfur.ath.cx



Code:
------
import std.stdio;
void main() {
    try {
        auto f = File("/non/existent/file").byLine();
    } catch(Exception e) {
        writeln(e.msg);
    }
}
------

Compile command:
------
dmd -O test.d
------

Program output:
------
Segmentation fault
------

Compiling without -O doesn't exhibit this problem.

Here's the stacktrace from gdb:












Looks like -O is causing the compiler to generate wrong code in this case.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 27 2013
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10723




P.S. The bug doesn't happen if the try-catch block is removed, or if the File
struct is assigned to a temporary variable first, then byLine called on it.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jul 27 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10723


Maxim Fomin <maxim maxim-fomin.ru> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |maxim maxim-fomin.ru



---
This is a variation of issue 9438

Gdb reports 0x0000000000444a99 in std.stdio.File.detach() (this=0x435e2e <D
main+130>)
    at std/stdio.d:426
426            if (_p.refs == 1)

Note that this parameter is 0x435e2e <D main+130> which means that this struct
pointer points to executable code instead of stack. Looking to _Dmain function:

Dump of assembler code for function _Dmain:
   0x0000000000435dac <+0>:    push   %rbp
   0x0000000000435dad <+1>:    mov    %rsp,%rbp
   0x0000000000435db0 <+4>:    sub    $0x78,%rsp
   0x0000000000435db4 <+8>:    push   %rbx
   0x0000000000435db5 <+9>:    push   %r12
   0x0000000000435db7 <+11>:    push   %r13
   0x0000000000435db9 <+13>:    push   %r14
   0x0000000000435dbb <+15>:    push   %r15
   0x0000000000435dbd <+17>:    xor    %ecx,%ecx
   0x0000000000435dbf <+19>:    mov    $0xa,%edx
   0x0000000000435dc4 <+24>:    lea    -0x48(%rbp),%rsi
   0x0000000000435dc8 <+28>:    mov    %rcx,-0x70(%rbp)
   0x0000000000435dcc <+32>:    mov    %rdx,-0x68(%rbp)
   0x0000000000435dd0 <+36>:    mov    %rsi,-0x60(%rbp)

<_TMP1+8>

<_TMP1>
   0x0000000000435de2 <+54>:    mov    %rax,%rcx
   0x0000000000435de5 <+57>:    mov    %rdx,%r8

<_TMP2+8>
---Type <return> to continue, or q <return> to quit---

<_TMP2>
   0x0000000000435df6 <+74>:    lea    -0x18(%rbp),%rbx
   0x0000000000435dfa <+78>:    xor    %rdi,%rdi
   0x0000000000435dfd <+81>:    mov    %rdi,(%rbx)
   0x0000000000435e00 <+84>:    mov    %rdi,0x8(%rbx)
   0x0000000000435e04 <+88>:    mov    %rdi,0x10(%rbx)
   0x0000000000435e08 <+92>:    mov    %rbx,%rdi
   0x0000000000435e0b <+95>:    callq  0x444464
<_D3std5stdio4File6__ctorMFNcAyaxAaZS3std5stdio4File>
   0x0000000000435e10 <+100>:    mov    %rax,%rdi
   0x0000000000435e13 <+103>:    mov    -0x70(%rbp),%rcx
   0x0000000000435e17 <+107>:    mov    -0x68(%rbp),%rdx
   0x0000000000435e1b <+111>:    mov    -0x60(%rbp),%rsi
   0x0000000000435e1f <+115>:    callq  0x4378d4
<_D3std5stdio4File15__T6byLineTaTaZ6byLineMFE3std6string14KeepTerminatoraZS3std5stdio4File15__T6ByLineTaTaZ6ByLine>
   0x0000000000435e24 <+120>:    mov    %rax,%r12
   0x0000000000435e27 <+123>:    callq  0x435e2e <_Dmain+130>
   0x0000000000435e2c <+128>:    jmp    0x435e37 <_Dmain+139>
   0x0000000000435e2e <+130>:    mov    %rbx,%rdi
   0x0000000000435e31 <+133>:    callq  0x44455c <_D3std5stdio4File6__dtorMFZv>
   0x0000000000435e36 <+138>:    retq   
---Type <return> to continue, or q <return> to quit---
   0x0000000000435e37 <+139>:    lea    -0x48(%rbp),%rdi
   0x0000000000435e3b <+143>:    callq  0x437c7c
<_D3std5stdio4File15__T6ByLineTaTaZ6ByLine11__fieldDtorMFZv>
   0x0000000000435e40 <+148>:    jmp    0x435e56 <_Dmain+170>
   0x0000000000435e42 <+150>:    mov    -0x58(%rbp),%rax
   0x0000000000435e46 <+154>:    mov    0x18(%rax),%rdx
   0x0000000000435e4a <+158>:    mov    0x10(%rax),%rdi
   0x0000000000435e4e <+162>:    mov    %rdx,%rsi
   0x0000000000435e51 <+165>:    callq  0x4388f4
<_D3std5stdio16__T7writelnTAyaZ7writelnFAyaZv>
   0x0000000000435e56 <+170>:    xor    %eax,%eax
   0x0000000000435e58 <+172>:    pop    %r15
   0x0000000000435e5a <+174>:    pop    %r14
   0x0000000000435e5c <+176>:    pop    %r13
   0x0000000000435e5e <+178>:    pop    %r12
   0x0000000000435e60 <+180>:    pop    %rbx
   0x0000000000435e61 <+181>:    mov    %rbp,%rsp
   0x0000000000435e64 <+184>:    pop    %rbp
   0x0000000000435e65 <+185>:    retq   
End of assembler dump.

gives that _Dmain+130 is instruction next to which druntime should upwind stack
in order to store in $rdi valid this struct pointer for further dtor calling. 

The reason is probably another
(https://github.com/D-Programming-Language/dmd/pull/1645) bug in
except_fillInEHTable() which incorrectly calculates sizes of instruction and
stores wrong offset in deh tables. In runtime exception code upwinds up to next
to correct instruction, so $rdi does not keep right pointer and program later
segfaults.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 08 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10723




---
Reduced:

struct File
{
    private struct Impl
    {
        uint refs = uint.max / 2;
    }
    private Impl* _p;
    private string _name;

    this(string name, in char[] stdioOpenmode = "rb")
    {
       _p = new Impl();
       _p.refs = 1;
       throw new Exception(name);
    }

    ~this() {
        assert(_p.refs);
        --_p.refs;
        _p = null;
    }

    int byLine() {
        return 0;
    }
}

void main() {
    try {
        int f = File("It's OK").byLine();
    } catch(Exception e) { }
}

Interesting is that if _name member or in char[] stdioOpenmode = "rb" are
removed, the program runs fine.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 15 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10723


Maxim Fomin <maxim maxim-fomin.ru> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |accepts-invalid



---


 Interesting is that if _name member or in char[] stdioOpenmode = "rb" are
 removed, the program runs fine.
This is actually a funny bug - in char[] stdioOpenmode = "rb" shouldn't compile in first place, this is accept-invalid. This erroneous default parameter as a result causes further problems with dehtables as offsets are wrong. https://github.com/D-Programming-Language/phobos/pull/1478 -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 15 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10723




---
Separate issue for dmd bug http://d.puremagic.com/issues/show_bug.cgi?id=10723

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Aug 15 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10723






 
 Interesting is that if _name member or in char[] stdioOpenmode = "rb" are
 removed, the program runs fine.
This is actually a funny bug - in char[] stdioOpenmode = "rb" shouldn't compile in first place, this is accept-invalid. This erroneous default parameter as a result causes further problems with dehtables as offsets are wrong. https://github.com/D-Programming-Language/phobos/pull/1478
Why is this invalid? I thought 'in char[]' just means const(char[]), which immutable(char)[] should be implicitly convertible to. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 15 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=10723


Maxim Fomin <maxim maxim-fomin.ru> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|accepts-invalid, pull       |



---



 
 Interesting is that if _name member or in char[] stdioOpenmode = "rb" are
 removed, the program runs fine.
This is actually a funny bug - in char[] stdioOpenmode = "rb" shouldn't compile in first place, this is accept-invalid. This erroneous default parameter as a result causes further problems with dehtables as offsets are wrong. https://github.com/D-Programming-Language/phobos/pull/1478
Why is this invalid? I thought 'in char[]' just means const(char[]), which immutable(char)[] should be implicitly convertible to.
Yes. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Aug 15 2013