(DMD) problem with closures/delegate literals and structs?
Iain Buclaw
ibuclaw at gdcproject.org
Sat Dec 7 06:45:10 PST 2013
On Dec 7, 2013 9:10 AM, "Johannes Pfau" <nospam at example.com> wrote:
>
> I found that ARM bug I said I found when testing dub on ARM.
>
> Turns out I was pretty stupid not testing this on X86 first, cause it's
> not ARM specific.... Debugging on a fast x86 machine would have been
> much more fun. Anyway, GDC right now can't compile dub:
>
> gdc -o bin/dub -fversion=DubUseCurl -I source
> -lcurl @build-files.txt
> bin/dub fetch vibe-d
> Fetching vibe-d 0.7.18...
> [1] 4139 segmentation fault (core dumped) bin/dub fetch vibe-d
>
> So I debugged this stuff and it's a stack corruption. Have a look at
> this example:
> http://dpaste.dzfl.pl/433c0a3d
>
> Please note that the this reference in the delegate points to the
> stack. Of course copying the struct doesn't magically change the
> address, so it still refers the old data.
>
> It looks like we actually generate a closure here which contains the
> this pointer instead of directly using the struct as a context pointer.
> That is probably an optimization bug in dmd, but it doesn't matter in
> this case as the problem would exist for closures and normal delegates.
>
> I'm wondering if this is according to the spec, but I guess it is. If
> we have a struct and take the address of a member funtion, the context
> pointer is a pointer to the struct (probably on stack) as well. So if
> we're in a member function and we have a delegate literal which
> accesses this it seems correct that we have a pointer to the struct
> (probably on stack). It can however be confusing:
>
> struct S
> {
> int a;
> void delegate() getDelegate(int b)
> {
> //b is in a closure and safe to access
> //but a is still accessed via this->a where
> //this may point to the stack.
> return () { return a + b; };
> }
> }
>
> So I guess I'm asking: Is this correct D behavior?
>
>
> BTW: The reason why we see this bug in gdc and not in dmd is simple:
> Because of GDC bug 52 NRVO doesn't work in gdc as in dmd. In dmd the
> address of the returned variable doesn't change. Dub returns HTTP
> structs by value. As long as the address doesn't change there's no
> issue, so DMDs NRVO hides this bug.
>
> However, as I now know how to break it it's easy to also break it on
> DMD ;-)
> http://dpaste.dzfl.pl/c109c2fd
>
> If the currect compiler behavior is correct - and I think it is - then
> std.net.curl is a ticking time bomb and needs to be fixed ASAP.
Ouch. I remember a similar conversation with David when he was writing
std.parallelism (the bug he ran into was code that assumed left to right
evaluation). I should hope that the author of std.net.curl didn't write
the module relying on this behavior.
Regards
--
Iain Buclaw
*(p < e ? p++ : p) = (c & 0x0f) + '0';
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/d.gnu/attachments/20131207/7af92e96/attachment.html>
More information about the D.gnu
mailing list