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