On Dec 7, 2013 9:10 AM, "Johannes Pfau" <nospam@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';