D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 6666 - gc finalization/freeing is hierarchy agnostic
Summary: gc finalization/freeing is hierarchy agnostic
Status: RESOLVED INVALID
Alias: None
Product: D
Classification: Unclassified
Component: druntime (show other issues)
Version: D2
Hardware: Other All
: P3 normal
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-09-13 17:58 UTC by Martin Nowak
Modified: 2011-09-13 21:18 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Martin Nowak 2011-09-13 17:58:47 UTC
class A
{
    ~this() {}
    void cleanup() {}
}

class B
{
    this(A a) { this.a = a; }
    ~this() { a.cleanup(); }
    A a;
}

void main() {
    auto a = new A();
    auto b = new B(a);
    // allocating a at a lower address than b causes it to be finalized earlier
    assert(cast(void*)b.a < cast(void*)b);
}
---

Finalization is done in memory order and does not take
hierarchies into account.
When b.a is finalized before b it's vtable is set to null, hence
a segfault will happen when accessing the vtable.
Anyhow a is destroyed before b even though it is referenced by b.

It seems like we need to somehow sort the to be finalized memory while
scanning.
Any cheap ideas to do that are welcome.
Comment 1 Vladimir Panteleev 2011-09-13 18:04:22 UTC
This is known, documented behavior. From http://www.d-programming-language.org/class.html#destructors :

> Furthermore, the order in which the garbage collector calls destructors for unreference objects is not specified. This means that when the garbage collector calls a destructor for an object of a class that has members that are references to garbage collected objects, those references may no longer be valid. This means that destructors cannot reference sub objects.

(In reply to comment #0)
> It seems like we need to somehow sort the to be finalized memory while
> scanning.

What about cyclic references?
Comment 2 Vladimir Panteleev 2011-09-13 18:05:56 UTC
Oops, I broke it.

> Furthermore, the order in which the garbage collector calls destructors
> for unreference objects is not specified. This means that when the garbage
> collector calls a destructor for an object of a class that has members that
> are references to garbage collected objects, those references may no longer
> be valid. This means that destructors cannot reference sub objects.
Comment 3 Martin Nowak 2011-09-13 21:18:40 UTC
Surprise, surprise.
Seems like there is not much one can reliably do in a finalizer.
Anyhow it was motivated by a C++ habit to do some clean up.