www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 8563] New: Exception segfault

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

           Summary: Exception segfault
           Product: D
           Version: D2
          Platform: x86_64
        OS/Version: All
            Status: NEW
          Severity: critical
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: daniel350 bigpond.com



PDT ---
http://dpaste.dzfl.pl/08d60e83

import std.exception : assertThrown;
import std.file : dirEntries, SpanMode;

// segfault does not occur with -O command line argument (exception is thrown
as expected with -O)
void main() {
      assertThrown(dirEntries("test", SpanMode.breadth)); // assert does not
fail, as expected (ie, exception was thrown)
      func("test");
}

void func(string suicide_variable) { // must be in a seperate function
      auto ax = suicide_variable; // uncomment this for a segfault in the
following statement
                                  // not clear as to why, can't yet reproduce
with other unpredictable exceptions (AFAIK)

      foreach(s; dirEntries("test", SpanMode.breadth)) {} // exception is
expected, not a segfault
}

----------

I tried to produce this behaviour for other functions (ie, without the
dirEntries call), but I could not get at it; but this is all still very much
undefined behaviour.

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


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

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



---
Reduced 

struct DirEntry
{
    string name;
}

struct DirIteratorImpl
{
    DirEntry _cur;
     property bool empty(){  return true; }
     property DirEntry front(){ return _cur; }
    void popFront() { }
}

struct RefCounted
{
    struct RefCountedStore
    {
        private struct Impl
        {
            DirIteratorImpl _payload;
            size_t _count;
        }

        private Impl* _store;

    }
    RefCountedStore _refCounted;

    ~this()
    {
        if (_refCounted._store)
            _refCounted._store._count = 0;
    }

    ref inout(DirIteratorImpl) refCountedPayload() inout
    {
        if (_refCounted._store)
            return _refCounted._store._payload;
        else
            throw new Exception("absent");
    }
    alias refCountedPayload this;
}

struct DirIterator
{
    RefCounted impl;
    this(string pathname)
    {
        throw new Exception("");
    }
     property bool empty(){ return impl.empty; }
     property DirEntry front(){ return impl.front; }
    void popFront(){ impl.popFront(); }
}

auto dirEntries(string path)
{
    return DirIterator(path);
}

void main() {
      foreach(s; dirEntries("test")) {} 
}

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




---
Further reduced:

struct Foo
{
    int[100] i;
}

struct DirIterator
{
    Foo* _store ;

    ~this()
    {
        if (_store)
        {
            _store.i = 0; // to segfault for sure
            _store = null;
        }
    }
    this(string pathname)
    {
        throw new Exception("");
    }
    void popFront() { }
    bool empty()  { return true; }
    Foo front() { return *_store; }
}

auto dirEntries()
{
    return DirIterator("path");
}

void main() {
    foreach(s; dirEntries()) {} 
}

This looks like issue 9438 (struct with pointer field and dtor) but now
temporaries from function return values are involved.

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




---
The reason of the issue seems to be in that struct temporary inside main() is
not initialized. If, line

foreach(s; dirEntries()) {} 

is replaced to directly accessing object

foreach(s; DirIterator("path")) {} 

dmd emits some code to clear the stack before assigning $rdi.

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


Nils <nilsbossung googlemail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |nilsbossung googlemail.com



---
*** Issue 10475 has been marked as a duplicate of this issue. ***

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




---
Some observations (includes the stuff form issue 10475):

struct DirIterator
{
    int _store = 42;
    this(string dummy) {throw new Exception("constructor");}
    ~this()
    {
        assert(_store == 42, "destructing garbage");
        assert(false, "destructor");
    }
}

DirIterator dirEntries() {return DirIterator("");}

void main()
{
    /* This triggers only "constructor". The destructor is not called. */
    version(A) DirIterator a = dirEntries();

    /* This triggers "constructor" and "destructing garbage".
    I.e. destructor is called on uninitialized data. Probably fine in this case
    because of explicit void initialization. */
    else version(B)
    {
        DirIterator b = void;
        b = dirEntries();
    }

    /* This triggers "constructor" and "destructor".
    Arguably, the destructor should not be called, since construction has
    failed. */
    else version(C) for(DirIterator c = DirIterator(""); true; ) {}

    /* Just like B, this triggers "constructor" and "destructing garbage".
    No explicit void initialization here, so that should not happen. */
    else version(D) for(DirIterator c = dirEntries(); true;) {}

    else static assert(false);
}

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




I posted bug 10475 fix and now it's merged in git head.
Could you please confirm the actual case by using git head?

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


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

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |FIXED



---

 I posted bug 10475 fix and now it's merged in git head.
 Could you please confirm the actual case by using git head?
This issue is also fixed. Thank you. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jul 02 2013