GC BUG: Referenced object destroyed before released

Graham St Jack grahams at acres.com.au
Sun Mar 16 15:28:04 PDT 2008


On Sun, 16 Mar 2008 16:45:14 +0300, Koroskin Denis wrote:

> 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...

I agree that this is a problem. Who cares if the two objects in question 
aren't referenced and more - their destructors should be called in the 
right order if it is possible to do so.

I guess the work-around (and maybe permanent) is to not reference any 
garbage-collected objects in your destructors. 




More information about the Digitalmars-d mailing list