Thread overview
Preventing nested struct destructor accessing stack frame
Dec 16, 2022
Nick Treleaven
Dec 16, 2022
Nick Treleaven
Dec 20, 2022
ag0aep6g
Dec 23, 2022
Nick Treleaven
December 16, 2022

This code segfaults when the GC calls the dtor after the unittest succeeds:

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?

December 16, 2022

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.

December 20, 2022
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.
December 23, 2022
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.
December 23, 2022

On 12/16/22 7:17 AM, Nick Treleaven wrote:

>

This code segfaults when the GC calls the dtor after the unittest succeeds:

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?

~this() { if(this !is this.init) ++i;}

Not ideal I guess, because really it's the context pointer you care about.

-Steve