April 28, 2013 Re: InvalidMemoryOperationError when calling functions from destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vladimir Panteleev | On Sat, 27 Apr 2013 07:58:25 -0700, Vladimir Panteleev <vladimir@thecybershadow.net> wrote:
> On Saturday, 27 April 2013 at 06:12:03 UTC, Steven Schveighoffer wrote:
>> On Thu, 25 Apr 2013 10:57:13 -0700, Vladimir Panteleev <vladimir@thecybershadow.net> wrote:
>>
>>> On Thursday, 25 April 2013 at 16:17:57 UTC, Jacob Carlborg wrote:
>>>> You cannot access GC controlled memory in class destructors.
>>>
>>> Not true.
>>
>> Can you be more specific? Maybe the wording was too strong. Should say "you shouldn't access GC controlled memory in class destructors."
>>
>> Or are you thinking of some specific case? Because the opposite of the above is DEFINITELY not true. I just want to make that clear.
>
> Last time I checked, destructors were called separately from deallocation. Thus, referencing memory will not result in undefined behavior. The order of destruction is non-deterministic, but otherwise, it's the same as accessing a clear()'d object, which is perfectly safe (from a memory safety perspective).
No, destructors are called along with deallocation. At the moment, the GC mutex is held while the collection is in progress, so it's not possible that a deallocated block could be reallocated before a dtor that references that block is called. But that is an implementation detail. There is no requirement for the GC to behave that way. In addition, there is no requirement for the GC to run in a specific thread, so if a destroyed object references a non-destroyed object, it's possible some thread is using the non-destroyed object while the dtor is using it in another thread, even if the object was only ever accessed from one thread!
-Steve
|
April 28, 2013 Re: InvalidMemoryOperationError when calling functions from destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Sunday, 28 April 2013 at 14:44:32 UTC, Steven Schveighoffer wrote: > On Sat, 27 Apr 2013 07:58:25 -0700, Vladimir Panteleev <vladimir@thecybershadow.net> wrote: > >> On Saturday, 27 April 2013 at 06:12:03 UTC, Steven Schveighoffer wrote: >>> On Thu, 25 Apr 2013 10:57:13 -0700, Vladimir Panteleev <vladimir@thecybershadow.net> wrote: >>> >>>> On Thursday, 25 April 2013 at 16:17:57 UTC, Jacob Carlborg wrote: >>>>> You cannot access GC controlled memory in class destructors. >>>> >>>> Not true. >>> >>> Can you be more specific? Maybe the wording was too strong. Should say "you shouldn't access GC controlled memory in class destructors." >>> >>> Or are you thinking of some specific case? Because the opposite of the above is DEFINITELY not true. I just want to make that clear. >> >> Last time I checked, destructors were called separately from deallocation. Thus, referencing memory will not result in undefined behavior. The order of destruction is non-deterministic, but otherwise, it's the same as accessing a clear()'d object, which is perfectly safe (from a memory safety perspective). > > No, destructors are called along with deallocation. At the moment, the GC mutex is held while the collection is in progress, so it's not possible that a deallocated block could be reallocated before a dtor that references that block is called. Right, so it makes no difference in practice. What I meant was that IIRC early versions of the GC used to rebuild internal free lists, and clobber freed data, in-loop with calling destructors. Thus, when referencing something in a destructor, sometimes you'd get the same object (not yet finalized), and sometimes you'd get garbage. Now you get a finalized object instead of garbage. > But that is an implementation detail. There is no requirement for the GC to behave that way. I don't disagree with you, but do we have a spec for GCs? I'd think preserving memory safety, even in a destructor, would be pretty important for a GC design. > In addition, there is no requirement for the GC to run in a specific thread, so if a destroyed object references a non-destroyed object, it's possible some thread is using the non-destroyed object while the dtor is using it in another thread, even if the object was only ever accessed from one thread! Sorry, not following. What's the problem? How is this related? |
April 28, 2013 Re: InvalidMemoryOperationError when calling functions from destructors | ||||
---|---|---|---|---|
| ||||
Posted in reply to Vladimir Panteleev | On Sun, 28 Apr 2013 16:25:06 -0700, Vladimir Panteleev <vladimir@thecybershadow.net> wrote: > On Sunday, 28 April 2013 at 14:44:32 UTC, Steven Schveighoffer wrote: >> No, destructors are called along with deallocation. At the moment, the GC mutex is held while the collection is in progress, so it's not possible that a deallocated block could be reallocated before a dtor that references that block is called. > > Right, so it makes no difference in practice. > > What I meant was that IIRC early versions of the GC used to rebuild internal free lists, and clobber freed data, in-loop with calling destructors. Thus, when referencing something in a destructor, sometimes you'd get the same object (not yet finalized), and sometimes you'd get garbage. Now you get a finalized object instead of garbage. This was not a "bug," probably (can't be definite on it, since I'm unaware of how the GC used to work). >> But that is an implementation detail. There is no requirement for the GC to behave that way. > > I don't disagree with you, but do we have a spec for GCs? AFAIK there is no spec, it's all based on the compiler implementation. For all I know, the GC on GDC or LDC may have a different API. > I'd think preserving memory safety, even in a destructor, would be pretty important for a GC design. I wouldn't expect it. code is code, not sure how you can guarantee memory safety in a dtor. >> In addition, there is no requirement for the GC to run in a specific thread, so if a destroyed object references a non-destroyed object, it's possible some thread is using the non-destroyed object while the dtor is using it in another thread, even if the object was only ever accessed from one thread! > > Sorry, not following. What's the problem? How is this related? Like an unlocked reference counter, let's say. It's only ever used in one thread. But then an object with a reference becomes garbage. Another thread then runs the garbage collector, enabling race conditions that would not normally be possible. -Steve |
Copyright © 1999-2021 by the D Language Foundation