www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - bug in garbage collection

reply Kevin Bealer <Kevin_member pathlink.com> writes:
I've discovered what I think is a bug in garbage collection.  An object's
constructor throws, but later on the destructor is run - it throws another
exception because the data[] was never assigned to a memory slice.

The object is an MmFile object.  The simplified test case is thus:

:
:import std.mmfile;
:import std.stdio;
:import std.gc;
:
:void other_function()
:{
:    char[] pos = "A";
:    
:    try {
:        pos = "A";
:        MmFile mink = new MmFile("/tmp/some/nonexistant/file");
:        pos = "B";
:    }
:    catch(Exception e) {
:        pos = pos ~ "C";
:    }
:    
:    writef("pos = %s.\n", pos);
:}
:
:int main()
:{
:    int pt = 0;
:    
:    try {
:        pt = 1;
:        other_function();
:        pt = 2;
:        std.gc.fullCollect();
:        pt = 3;
:    }
:    catch(Exception e) {
:        pt += 100;
:    }
:    
:    writef("at pt %d.\n", pt);
:    
:    return 0;
:}


Notes:

1. The problem goes away with a modified copy of the MmFile -- if the destructor
has an "if(data)" around the munmap().  This should not be necessary, because
the constructor is throwing an exception.

2. DMD version is 0.112.

3. The output from my run is:

--
open error, errno = 2
pos = AC.
at pt 102.
--

4. In other words, MmFile (which was never completely constructed) is throwing
an exception in the destructor.  I have verified this by putting a printf() in
the destructor for a modified MmFile object.

5. You can see "munmap(0,0)" in the strace() output from Linux.

Kevin
Feb 04 2005
parent Thomas Kuehne <thomas-dloop kuehne.thisisspam.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Kevin Bealer schrieb am Sat, 5 Feb 2005 05:38:03 +0000 (UTC):
 I've discovered what I think is a bug in garbage collection.  An object's
 constructor throws, but later on the destructor is run - it throws another
 exception because the data[] was never assigned to a memory slice.

 The object is an MmFile object.  The simplified test case is thus:

:
:import std.mmfile;
:import std.stdio;
:import std.gc;
:
:void other_function()
:{
:    char[] pos = "A";
:    
:    try {
:        pos = "A";
:        MmFile mink = new MmFile("/tmp/some/nonexistant/file");
:        pos = "B";
:    }
:    catch(Exception e) {
:        pos = pos ~ "C";
:    }
:    
:    writef("pos = %s.\n", pos);
:}
:
:int main()
:{
:    int pt = 0;
:    
:    try {
:        pt = 1;
:        other_function();
:        pt = 2;
:        std.gc.fullCollect();
:        pt = 3;
:    }
:    catch(Exception e) {
:        pt += 100;
:    }
:    
:    writef("at pt %d.\n", pt);
:    
:    return 0;
:}


 Notes:

 1. The problem goes away with a modified copy of the MmFile -- if the
destructor
 has an "if(data)" around the munmap().  This should not be necessary, because
 the constructor is throwing an exception.
Added to DStress as http://dstress.kuehne.cn/run/destructor_04.d Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFCBU/03w+/yD4P9tIRAvq7AJ9X1XmuCl5ggogpHDIkZ4S5KiePxgCgyHBZ 52xnUU54p3H+/SmedOrhWvU= =uSFk -----END PGP SIGNATURE-----
Feb 05 2005