GC BUG: Referenced object destroyed before released
Koroskin Denis
2korden at gmail.com
Sun Mar 16 06:45:14 PDT 2008
Hello, community!
Consider the following code:
// For those who prefer alternative reality ;)
version(Tango) extern(C) void printf(char[] s, ...);
class Resource
{
private char[] data;
private bool released;
this()
{
this.data = null;
this.released = false;
}
~this()
{
printf("Resource destroyed\n");
}
void release()
{
released = true;
}
}
class Owner
{
private Resource res;
this(Resource res) {
this.res = res;
}
~this()
{
res.release();
printf("Owner destroyed\n");
}
}
int main()
{
Resource res = new Resource();
Owner owner = new Owner(res);
printf("Main exit\n");
return 0;
}
In this code we don't explicitly destroy anything, so GC chooses the order
of object destruction. And it chooses wrong.
"Phobos hack" shows the following stack trace upon exit:
Main exit
Resource destroyed
Unhandled win32 exception!
Error: Access Violation (object.Exception)
backtrace:
00402087 void crash.Owner._dtor() (+f) crash.d:35
0040262a _d_callfinalizer (+46)
004025dd void std.gc.new_finalizer(void*, bool) (+9)
004066c3 void gcx.GC.fullCollectNoStack() (+3b)
0040226f gc_term (+b)
00415b6d mainCRTStartup (+a9)
7c816d4f ???
or without it:
Main exit
Resource destroyed
Error: Access Violation
or with Tango:
object.Exception: Access Violation
tango.core.Exception.FinalizeException: An exception was thrown while
finalizing an instance of class crash.Resource
object.Exception: Access Violation
Was there any bug report filled on this bug? It's very annoying, since it
makes your program not reliable in runtime. At least, if it was a
compilation bug, and I managed to bypass it, I would be assured, that the
resulted program whould behave predictable. Yet, it is not...
More information about the Digitalmars-d
mailing list