Hungry Mind , Blog about everything in IT - C#, Java, C++, .NET, Windows, WinAPI, ...

__await is still broken in Visual Studio 2015 RTM

Connect issue

The following simple code does not work:

#include "stdafx.h"
#include <experimental\generator>
#include <future>

using namespace std;
using namespace std::experimental;

future<int> get_int()
{
    return async([] { return 0; });
}

future<int> wait_int()
{
    return __await get_int();
}


int main()
{
    auto const i = wait_int().get();
    return 0;
}

App hits int 3 instruction (XXX.exe has triggered a breakpoint) and then hangs forever waiting for suspended coroutine to finish. Bravo! My investigation shows that compiler generates invalid instructions within XXX.exe!wait_int$_ResumeCoro$2() function:

00007FF6166FB0F0  mov         qword ptr [rsp+8],rcx  
00007FF6166FB0F5  push        rbp  
00007FF6166FB0F6  sub         rsp,30h  
00007FF6166FB0FA  mov         qword ptr [rsp+20h],0FFFFFFFFFFFFFFFEh  
00007FF6166FB103  mov         rbp,qword ptr [$S2]  
00007FF6166FB108  mov         eax,dword ptr [rbp+20h]  
00007FF6166FB10B  mov         dword ptr [rbp+78h],eax  
00007FF6166FB10E  cmp         dword ptr [rbp+78h],5  

rbp has the address of coroutine frame, frame has two consequent 64-bit values - address of resume method and some internal state flag, which is set to 2 initially. dword ptr [rbp+20h] - this instruction obtains the flag, but the offset is completely wrong, it must be dword ptr [rbp+8h]. So all cases of state flag switch are bypassed. Default case makes the assert hit. Boom.

UPD: It doesn't support Debug Information Format == Program Database for Edit And Continue (/Zl). With this setting set to something else the code is generated properly: mov eax, [rbp+8].

Lindemann

Он бесподобен, я хочу от него детей!!!!!!11

Copyright 2007-2011 Chabster