www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Preventing nested struct destructor accessing stack frame

reply Nick Treleaven <nick geany.org> writes:
This code segfaults when the GC calls the dtor after the unittest 
succeeds:

```d
unittest
{
     int i;
     struct S
     {
         ~this() { i++; }
     }
     (*new S).destroy;
}
```

It seems destroy clears the context pointer. Is there a way to 
test if the context pointer is null in the dtor, to prevent the 
increment?
Dec 16 2022
next sibling parent reply Nick Treleaven <nick geany.org> writes:
On Friday, 16 December 2022 at 12:17:40 UTC, Nick Treleaven wrote:
 It seems destroy clears the context pointer. Is there a way to 
 test if the context pointer is null in the dtor, to prevent the 
 increment?
This seems to work: ~this() trusted { if (&i > cast(void*)1024) i++; } It would be better if there was a struct property to get the context pointer though.
Dec 16 2022
parent reply ag0aep6g <anonymous example.com> writes:
On 16.12.22 14:07, Nick Treleaven wrote:
 This seems to work:
 
          ~this()  trusted { if (&i > cast(void*)1024) i++; }
 
 It would be better if there was a struct property to get the context 
 pointer though.
A quick test suggests that the context pointer is the last item in `tupleof`. So this might do the trick: ~this() { if (this.tupleof[$ - 1] !is null) i++; } I don't know if it's guaranteed to work though. Might be an implementation detail.
Dec 19 2022
parent Nick Treleaven <nick geany.org> writes:
On Tuesday, 20 December 2022 at 06:31:09 UTC, ag0aep6g wrote:
 On 16.12.22 14:07, Nick Treleaven wrote:
 This seems to work:
 
          ~this()  trusted { if (&i > cast(void*)1024) i++; }
 
 It would be better if there was a struct property to get the 
 context pointer though.
A quick test suggests that the context pointer is the last item in `tupleof`. So this might do the trick: ~this() { if (this.tupleof[$ - 1] !is null) i++; } I don't know if it's guaranteed to work though. Might be an implementation detail.
Great, thanks. The struct tupleof docs just link to the class tupleof docs, which say:
 The order of the fields in the tuple matches the order in which 
 the fields are declared.
So I think for a struct the context pointer has to come after any fields.
Dec 23 2022
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 12/16/22 7:17 AM, Nick Treleaven wrote:
 This code segfaults when the GC calls the dtor after the unittest succeeds:
 
 ```d
 unittest
 {
      int i;
      struct S
      {
          ~this() { i++; }
      }
      (*new S).destroy;
 }
 ```
 
 It seems destroy clears the context pointer. Is there a way to test if 
 the context pointer is null in the dtor, to prevent the increment?
Check if the struct is the init value? ```d ~this() { if(this !is this.init) ++i;} ``` Not ideal I guess, because really it's the context pointer you care about. -Steve
Dec 23 2022