none
CancelIoEx hangs program RRS feed

  • Question

  • Hi,

    I have a large program that episodically hangs on Windows systems (Go language runtime). I've tracked the issue down to interaction of asynchronous network IO completion and CancelIoEx. Below is the minimized repro program and winsock trace log.

    The program prints some amount of dots and then completely hangs. Any attempts to kill the process do not succeed -- it remains semi-alive with a single thread deadlocked in kernel.

    My system is 64-bit Windows 7 SP1 Home Extended, Intel Q720 CPU. It was also observed on some Windows Server Datacenter SP2, but I don't have details about that system.

    For now it looks like a kernel bug to me. Any suggestions/workarounds are welcome. TIA

    Here is winsock trace log. It uses 32K send buffers, while the program below uses 8K send blocks (the probability of hang depends on the sizes of buffers). I've noticed that there is usually partial receive before the hang (in this case it returns 1088 bytes into 8192 byte buffer), and then the hanging read does not use FastPath (you can see that it uses kernel provided buffer, while previous receives use user provided buffer):

    Event Name,       Type,     Event ID,    Version,    Channel,      Level,     Opcode,       Task,            Keyword,        PID,        TID,     Processor Number,  Instance ID,   Parent Instance ID,                              Activity ID,                      Related Activity ID,           Clock-Time, Kernel(ms),   User(ms), User Data
    Microsoft-Windows-Winsock Network Event ,         1000,          0,         16,          4,         10,       1000, 0x0000000000000006, 0x000004A4, 0x0000129C,                    4,             ,                     ,   {07dbe8e0-fa80-ffff-0000-000000000000},                                         ,   130194069442625794,          0,          0,        0,     1002, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0,        2, "SOCK_STREAM ",        6, 0x4A4, 0x0
    Microsoft-Windows-Winsock Network Event ,         1000,          0,         16,          4,         10,       1000, 0x0000000000000006, 0x000004A4, 0x0000129C,                    4,             ,                     ,   {07dbe8e0-fa80-ffff-0000-000000000000},                                         ,   130194069442625871,          0,          0,        1,     1012, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0,        0,        0,        0, 0x4A4, 0x0
    Microsoft-Windows-Winsock Network Event ,         1030,          0,         16,          4,         10,       1030, 0x0000000000000006, 0x000004A4, 0x0000129C,                    4,             ,                     ,   {07dbe8e0-fa80-ffff-0000-000000000000},                                         ,   130194069442626018,          0,          0,        0,     7016, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0, 0x0,       16, "0.0.0.0"
    Microsoft-Windows-Winsock Network Event ,         1030,          0,         16,          4,         12,       1030, 0x0000000000000006, 0x000004A4, 0x0000129C,                    4,             ,                     ,   {07dbe8e0-fa80-ffff-0000-000000000000},                                         ,   130194069442626365,          0,          0,        1,     7018, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0, 0x0,       16, "0.0.0.0:6630"
    Microsoft-Windows-Winsock Network Event ,         1021,          0,         16,          4,         11,       1021, 0x0000000000000006, 0x000004A4, 0x0000129C,                    4,             ,                     ,   {07dbe8e0-fa80-ffff-0000-000000000000},                                         ,   130194069442626525,          0,          0,        0,     5031, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0, 0xFFFFFA800731EF00,        0, 0x0,       16, "127.0.0.1:6584"
    Microsoft-Windows-Winsock Network Event ,          0,         3001,          0,         16,          4,          0,       3001, 0x000000000000000A, 0x000004A4, 0x0000129C,                    4,             ,                     ,   {08e591a0-fa80-ffff-0000-000000000000},                                         ,   130194069442626846,          0,          0,        3,     6500, 0xFFFFFA8004968260, 0xFFFFFA8008E591A0, 0x0,       16, "127.0.0.1:6630",        0
    Microsoft-Windows-Winsock Network Event ,         1020,          0,         16,          4,         12,       1020, 0x0000000000000006, 0x000004A4, 0x0000129C,                    4,             ,                     ,   {07dbe8e0-fa80-ffff-0000-000000000000},                                         ,   130194069442627000,          0,          0,        1,     5032, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0, 0x0
    Microsoft-Windows-Winsock Network Event ,         1027,          0,         16,          4,         12,       1027, 0x0000000000000006, 0x00000004, 0x00000040,                    6,             ,                     ,   {08e591a0-fa80-ffff-0000-000000000000},                                         ,   130194069442627436,       3915,          0,        1,     6101, 0xFFFFFA8004968260, 0xFFFFFA8008E591A0, 0xFFFFFA8008D8A9F0,        0, 0x0,       16, "127.0.0.1:6630", 0xFFFFFA8008BD24A0,        0
    Microsoft-Windows-Winsock Network Event ,         1004,          0,         16,          4,         12,       1004, 0x0000000000000006, 0x000004A4, 0x0000129C,                    4,             ,                     ,   {045aa360-fa80-ffff-0000-000000000000},                                         ,   130194069442627475,          0,          0,        0,     4107, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0,        1, 0xFFFFFA80045F8480,     8192, 0x0
    Microsoft-Windows-Winsock Network Event ,         1000,          0,         16,          4,         10,       1000, 0x0000000000000006, 0x000004A4, 0x0000131C,                    4,             ,                     ,   {0a734010-fa80-ffff-0000-000000000000},                                         ,   130194069442627892,         15,         30,        0,     1002, 0xFFFFFA8004968260, 0xFFFFFA800A734010,        2, "SOCK_STREAM ",        6, 0x4A4, 0x0
    Microsoft-Windows-Winsock Network Event ,         1000,          0,         16,          4,         10,       1000, 0x0000000000000006, 0x000004A4, 0x0000131C,                    4,             ,                     ,   {0a734010-fa80-ffff-0000-000000000000},                                         ,   130194069442627975,         15,         30,        1,     1012, 0xFFFFFA8004968260, 0xFFFFFA800A734010,        0,        0,        0, 0x4A4, 0x0
    Microsoft-Windows-Winsock Network Event ,         1026,          0,         16,          4,         11,       1026, 0x0000000000000006, 0x000004A4, 0x0000131C,                    4,             ,                     ,   {08e591a0-fa80-ffff-0000-000000000000},                                         ,   130194069442628090,         15,         30,        0,     6024, 0xFFFFFA8004968260, 0xFFFFFA8008E591A0, 0x0
    Microsoft-Windows-Winsock Network Event ,         1003,          0,         16,          4,         12,       1003, 0x0000000000000016, 0x000004A4, 0x0000131C,                    4,             ,                     ,   {0b1ea000-fa80-ffff-0000-000000000000},                                         ,   130194069442628860,         15,         30,        0,     3047, 0xFFFFFA8004968260, 0xFFFFFA8008BD24A0,        1, 0xFFFFFA800B1EA208,    32768, 0x0
    Microsoft-Windows-Winsock Network Event ,         1003,          0,         16,          4,         12,       1003, 0x0000000000000016, 0x000004A4, 0x0000131C,                    4,             ,                     ,   {0b1ea000-fa80-ffff-0000-000000000000},                                         ,   130194069442628924,         15,         30,        1,     3051, 0xFFFFFA8004968260, 0xFFFFFA8008BD24A0,        1, 0xFFFFFA800B1EA208,    32768, 0x0
    Microsoft-Windows-Winsock Network Event ,         1003,          0,         16,          4,         12,       1003, 0x0000000000000006, 0x000004A4, 0x000008C4,                    4,             ,                     ,   {045e1700-fa80-ffff-0000-000000000000},                                         ,   130194069442630220,         15,         30,        0,     3003, 0xFFFFFA8004968260, 0xFFFFFA8008BD24A0,        1, 0xFFFFFA8007E58210,    32768, 0x0
    Microsoft-Windows-Winsock Network Event ,         1003,          0,         16,          4,         12,       1003, 0x0000000000000026, 0x000009CC, 0x00000A98,                    6,             ,                     ,   {0b1ea000-fa80-ffff-0000-000000000000},                                         ,   130194069442630676,        435,       1770,        1,     3024, 0xFFFFFA8004968260, 0xFFFFFA8008BD24A0,        1, 0xFFFFFA800B1EA208,    32768, 0x0
    Microsoft-Windows-Winsock Network Event ,         1003,          0,         16,          4,         12,       1003, 0x0000000000000006, 0x000004A4, 0x000008C4,                    4,             ,                     ,   {045e1700-fa80-ffff-0000-000000000000},                                         ,   130194069442630804,         15,         30,        1,     3018, 0xFFFFFA8004968260, 0xFFFFFA8008BD24A0,        1, 0xFFFFFA8007E58210,    32768, 0x0
    Microsoft-Windows-Winsock Network Event ,         1004,          0,         16,          4,         12,       1004, 0x0000000000000016, 0x000004A4, 0x000008C4,                    4,             ,                     ,   {a185ad9f-001f-0000-0000-000000000000},                                         ,   130194069442631099,         15,         30,        0,     4115, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0,        1, 0xC08403F000,     8192, 0x0
    Microsoft-Windows-Winsock Network Event ,         1004,          0,         16,          4,         12,       1004, 0x0000000000000016, 0x000004A4, 0x000008C4,                    4,             ,                     ,   {a185ad9f-001f-0000-0000-000000000000},                                         ,   130194069442631105,         15,         30,        1,     4116, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0,        1, 0xC08403F000,     8192, 0x0
    Microsoft-Windows-Winsock Network Event ,         1003,          0,         16,          4,         12,       1003, 0x0000000000000006, 0x000004A4, 0x000008C4,                    4,             ,                     ,   {0b723010-fa80-ffff-0000-000000000000},                                         ,   130194069442631766,         15,         30,        0,     3003, 0xFFFFFA8004968260, 0xFFFFFA8008BD24A0,        1, 0xFFFFFA8008EC4B80,    32768, 0x0
    Microsoft-Windows-Winsock Network Event ,         1004,          0,         16,          4,         12,       1004, 0x0000000000000016, 0x000004A4, 0x000008C4,                    4,             ,                     ,   {a185ad9f-001f-0000-0000-000000000000},                                         ,   130194069442632093,         15,         30,        0,     4115, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0,        1, 0xC08403F000,     8192, 0x0
    Microsoft-Windows-Winsock Network Event ,         1004,          0,         16,          4,         12,       1004, 0x0000000000000016, 0x000004A4, 0x000008C4,                    4,             ,                     ,   {a185ad9f-001f-0000-0000-000000000000},                                         ,   130194069442632100,         15,         30,        1,     4116, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0,        1, 0xC08403F000,     8192, 0x0
    Microsoft-Windows-Winsock Network Event ,         1004,          0,         16,          4,         12,       1004, 0x0000000000000016, 0x000004A4, 0x000008C4,                    4,             ,                     ,   {a185ad9f-001f-0000-0000-000000000000},                                         ,   130194069442632607,         15,         30,        0,     4115, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0,        1, 0xC08403F000,     8192, 0x0
    Microsoft-Windows-Winsock Network Event ,         1004,          0,         16,          4,         12,       1004, 0x0000000000000016, 0x000004A4, 0x000008C4,                    4,             ,                     ,   {a185ad9f-001f-0000-0000-000000000000},                                         ,   130194069442632607,         15,         30,        1,     4116, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0,        1, 0xC08403F000,     8192, 0x0
    Microsoft-Windows-Winsock Network Event ,         1004,          0,         16,          4,         12,       1004, 0x0000000000000016, 0x000004A4, 0x000008C4,                    4,             ,                     ,   {a185ad9f-001f-0000-0000-000000000000},                                         ,   130194069442632780,         15,         30,        0,     4115, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0,        1, 0xC08403F000,     8192, 0x0
    Microsoft-Windows-Winsock Network Event ,         1004,          0,         16,          4,         12,       1004, 0x0000000000000016, 0x000004A4, 0x000008C4,                    4,             ,                     ,   {a185ad9f-001f-0000-0000-000000000000},                                         ,   130194069442632780,         15,         30,        1,     4116, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0,        1, 0xC08403F000,     8192, 0x0
    Microsoft-Windows-Winsock Network Event ,         1004,          0,         16,          4,         12,       1004, 0x0000000000000016, 0x000004A4, 0x000008C4,                    4,             ,                     ,   {a185ad9f-001f-0000-0000-000000000000},                                         ,   130194069442632844,         15,         30,        0,     4115, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0,        1, 0xC08403F000,     8192, 0x0
    Microsoft-Windows-Winsock Network Event ,         1004,          0,         16,          4,         12,       1004, 0x0000000000000016, 0x000004A4, 0x000008C4,                    4,             ,                     ,   {a185ad9f-001f-0000-0000-000000000000},                                         ,   130194069442632844,         15,         30,        1,     4116, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0,        1, 0xC08403F000,     8192, 0x0
    Microsoft-Windows-Winsock Network Event ,         1004,          0,         16,          4,         12,       1004, 0x0000000000000016, 0x000004A4, 0x000008C4,                    4,             ,                     ,   {a185ad9f-001f-0000-0000-000000000000},                                         ,   130194069442632882,         15,         30,        0,     4115, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0,        1, 0xC08403F000,     8192, 0x0
    Microsoft-Windows-Winsock Network Event ,         1004,          0,         16,          4,         12,       1004, 0x0000000000000016, 0x000004A4, 0x000008C4,                    4,             ,                     ,   {a185ad9f-001f-0000-0000-000000000000},                                         ,   130194069442632889,         15,         30,        1,     4116, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0,        1, 0xC08403F000,     1088, 0x0
    Microsoft-Windows-Winsock Network Event ,         1004,          0,         16,          4,         12,       1004, 0x0000000000000006, 0x000004A4, 0x000008C4,                    4,             ,                     ,   {08e514d0-fa80-ffff-0000-000000000000},                                         ,   130194069442633582,         15,         30,        0,     4107, 0xFFFFFA8004968260, 0xFFFFFA8007DBE8E0,        1, 0xFFFFFA80048AF470,     8192, 0x0 

    At this point the program deadlocks.

    Below is the reproducer:

    #include <stdio.h>
    #include <stdlib.h>
    #include <process.h>
    #include <WinSock2.h>
    #include <Mswsock.h>
    #include <Windows.h>
    
    static void test(void);
    static void panic(const char*);
    static unsigned __stdcall client(void*);
    static unsigned __stdcall canceler(void*);
    
    int main(int argc, char **argv)
    {
      SetProcessAffinityMask((HANDLE)-1, 1);
      WSADATA wsaData;
      WSAStartup(MAKEWORD(2, 2), &wsaData);
      for(;;)
        test();
    }
    
    static void
    test(void)
    {
      printf(".");
      SOCKET s;
      s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, WSA_FLAG_OVERLAPPED);
      if(s == INVALID_SOCKET)
        panic("socket");
      sockaddr_in addr;
      addr.sin_family = AF_INET;
      addr.sin_addr.s_addr = inet_addr("127.0.0.1");
      addr.sin_port = 0;
      if(bind(s, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR)
        panic("bind");
      if(listen(s, SOMAXCONN) == SOCKET_ERROR)
        panic("listen");
      int len = sizeof(addr);
      if(getsockname(s, (SOCKADDR*)&addr, &len) == SOCKET_ERROR)
        panic("getsockname");
      HANDLE ct = (HANDLE)_beginthreadex(0, 0, client, (void*)addr.sin_port, 0, 0);
      if(ct == (HANDLE)-1)
        panic("_beginthreadex");
      SOCKET c = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, WSA_FLAG_OVERLAPPED);
      if(c == INVALID_SOCKET)
        panic("WSASocket");
      OVERLAPPED ol0 = {};
      DWORD recv = 0;
      char tmp[1024];
      if(!AcceptEx(s, c, tmp, 0, 512, 512, &recv, &ol0) && GetLastError() != WSA_IO_PENDING)
        panic("AcceptEx");
      DWORD flags;
      if(!WSAGetOverlappedResult(s, &ol0, &recv, 1, &flags))
        panic("WSAGetOverlappedResult");
      int yes = 1;
      if(setsockopt(c, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes)) == SOCKET_ERROR)
        panic("setsockopt");
      const int sendbuf = 8*1024;
      void *buf = VirtualAlloc(0, sendbuf, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
      if(buf == 0)
        panic("VirtualAlloc");
      for(;;) {
        OVERLAPPED ol = {};
        WSABUF b;
        b.buf = (char*)buf;
        b.len = sendbuf;
        if(WSASend(c, &b, 1, 0, 0, &ol, 0) == SOCKET_ERROR && GetLastError() != WSA_IO_PENDING) {
          if(GetLastError() == WSAECONNABORTED || GetLastError() == WSAECONNRESET)
            break;
          panic("WSASend");
        }
        DWORD sent = 0, flags = 0;
        if(!WSAGetOverlappedResult(c, &ol, &sent, 1, &flags)) {
          if(GetLastError() == WSAECONNABORTED || GetLastError() == WSAECONNRESET)
            break;
          panic("WSAGetOverlappedResult");
        }
        if(sent != sendbuf) {
          printf("sent %d/%d\n", sent, sendbuf);
          exit(1);
        }
      }
      VirtualFree(buf, sendbuf, MEM_RELEASE);
      if(WaitForSingleObject(ct, INFINITE) != WAIT_OBJECT_0)
        panic("WaitForSingleObject");
      closesocket(c);
      closesocket(s);
    }
    
    struct cancel_t
    {
       SOCKET c;
       OVERLAPPED* ol;
    };
    
    static unsigned __stdcall
    client(void *arg)
    {
      SOCKET c = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, WSA_FLAG_OVERLAPPED);
      if(c == INVALID_SOCKET)
        panic("socket");
      sockaddr_in addr;
      addr.sin_family = AF_INET;
      addr.sin_addr.s_addr = inet_addr("127.0.0.1");
      addr.sin_port = (unsigned)arg;
      if(connect(c, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR)
        panic("connect");
      int yes = 1;
      if(setsockopt(c, IPPROTO_TCP, TCP_NODELAY, (char*)&yes, sizeof(yes)) == SOCKET_ERROR)
        panic("setsockopt");
      const int recvbuf = 8*1024;
      void *buf = VirtualAlloc(0, recvbuf, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
      if(buf == 0)
        panic("VirtualAlloc");
      OVERLAPPED ol = {};
      cancel_t can = {c, &ol};
      HANDLE ct = (HANDLE)_beginthreadex(0, 0, canceler, &can, 0, 0);
      if(ct == (HANDLE)-1)
        panic("_beginthreadex");
      for(;;) {
        WSABUF b;
        b.buf = (char*)buf;
        b.len = recvbuf;
        DWORD recv = 0, flags = 0;
        if(WSARecv(c, &b, 1, &recv, &flags, &ol, 0) == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
          panic("WSARecv");
        if(!WSAGetOverlappedResult(c, &ol, &recv, 1, &flags)) {
          if(GetLastError() == WSA_OPERATION_ABORTED)
            break;
          panic("WSAGetOverlappedResult");
        }
      }
      VirtualFree(buf, recvbuf, MEM_RELEASE);
      closesocket(c);
      if(WaitForSingleObject(ct, INFINITE) != WAIT_OBJECT_0)
        panic("WaitForSingleObject");
      return 0;
    }
    
    static unsigned __stdcall
    canceler(void *arg)
    {
      cancel_t *can = (cancel_t*)arg;
      for(;;) {
        Sleep(0);
        if(!CancelIoEx((HANDLE)can->c, can->ol)) {
          if(GetLastError() == ERROR_INVALID_HANDLE)
            break;
          if(GetLastError() == ERROR_NOT_FOUND)
            continue;
          panic("CancelIoEx");
        }
      }
      return 0;
    }
    
    static void
    panic(const char *what)
    {
      printf("%s failed with %d\n", what, GetLastError());
      exit(1);
    }


    Sunday, July 28, 2013 10:47 AM

All replies

  • Once I've uninstalled AVG antivirus, the problem has gone away.

    Tuesday, July 30, 2013 10:24 AM