CancelIoEx вешает программу
От: remark Россия http://www.1024cores.net/
Дата: 28.07.13 11:16
Оценка:
Следующая программа зависает через несколько секунд/минут работы. Виснет наглухо — попытки убить ее любыми способами ни к чему не приводят. Она висит с одним потоком задедлоченым в ядре. Попытки смотреть на нее через Process Explorer 64 несколько раз приводили к BSOD, хотя конечно это может быть просто ошибка в ProcExp.

Видит ли кто-нибудь глупую ошибку в программе? Может воспроизвести?
У меня это воспроизводится на 64-bit Windows 7 SP1 Home Extended, Intel Q720 CPU. Это было замечено на других серверных версиях, но я не знаю деталей.
Вот баг в Microsoft.

Так же есть winsock trace. Трейс снят с 32К буфером на отправку, а программа внизу использует 8К буфер, но сути это не меняет.
Я заметил, что предыдущее чтение всегда (?) возвращает не полный буфер, в данном случае 1088 байт. А сама зависающая операция не использует FastPath, это видно по адресу буфера — она использует ядерный буфер, а предыдущие чтения используют пользовательский буфер.

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


Вот собственно репродьюсер:

#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);
}



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
winsock
Re: CancelIoEx вешает программу
От: acDev Россия  
Дата: 29.07.13 07:50
Оценка:
Здравствуйте, remark, Вы писали:

R> OVERLAPPED ol = {};

R> cancel_t can = {c, &ol};
R> HANDLE ct = (HANDLE)_beginthreadex(0, 0, canceler, &can, 0, 0);
R> for(;) {
R> WSABUF b;
R> b.buf = (char*)buf;
R> b.len = recvbuf;
R> DWORD recv = 0, flags = 0;
R> if(WSARecv(c, &b, 1, &recv, &flags, &ol, 0) == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
R> panic("WSARecv");
R> if(!WSAGetOverlappedResult(c, &ol, &recv, 1, &flags)) {

R>static unsigned __stdcall

R>canceler(void *arg)
R>{
R> cancel_t *can = (cancel_t*)arg;
R> for(;) {
R> Sleep(0);
R> if(!CancelIoEx((HANDLE)can->c, can->ol)) {

Почему в структуре OVERLAPPED поле hEvent не определено?
Почему структура OVERLAPPED одновременно используется в двух потоках?
И что вы этим кодом вообще хотели добиться?
Re[2]: CancelIoEx вешает программу
От: remark Россия http://www.1024cores.net/
Дата: 29.07.13 13:58
Оценка:
Здравствуйте, acDev, Вы писали:

D>Здравствуйте, remark, Вы писали:


R>> OVERLAPPED ol = {};

R>> cancel_t can = {c, &ol};
R>> HANDLE ct = (HANDLE)_beginthreadex(0, 0, canceler, &can, 0, 0);
R>> for(;) {
R>> WSABUF b;
R>> b.buf = (char*)buf;
R>> b.len = recvbuf;
R>> DWORD recv = 0, flags = 0;
R>> if(WSARecv(c, &b, 1, &recv, &flags, &ol, 0) == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
R>> panic("WSARecv");
R>> if(!WSAGetOverlappedResult(c, &ol, &recv, 1, &flags)) {

R>>static unsigned __stdcall

R>>canceler(void *arg)
R>>{
R>> cancel_t *can = (cancel_t*)arg;
R>> for(;) {
R>> Sleep(0);
R>> if(!CancelIoEx((HANDLE)can->c, can->ol)) {

D>Почему в структуре OVERLAPPED поле hEvent не определено?


Его разве обязательно определять? WSAGetOverlappedResult() может работать без него, тогда он смотрит на "состояние дескриптора". В боевой программе используется GQCS, которому тоже не нужен евент.

D>Почему структура OVERLAPPED одновременно используется в двух потоках?


Потому что так происходит в боевой программе. Это нормально, т.к. CancelIoEx предназначена для отмены операций, запущенных в других потоках.

D>И что вы этим кодом вообще хотели добиться?


Это минимальный репродьюсер проблемы из большой программы.
Это не так важно. Важно — должна ли эта, пусть и глупая, программа работать или нет? Глупая программа не должна вешать ядро и приводить к BSOD, правильно?

Большая программа — это рантайм языка Go:
https://code.google.com/p/go/source/browse/src/pkg/net/fd_windows.go
https://code.google.com/p/go/source/browse/src/pkg/runtime/netpoll_windows.c
https://code.google.com/p/go/source/browse/src/pkg/runtime/netpoll.goc
Но в нём сложно разбираться.

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: CancelIoEx вешает программу
От: okman Беларусь https://searchinform.ru/
Дата: 29.07.13 14:25
Оценка:
Здравствуйте, remark, Вы писали:

R>Следующая программа зависает через несколько секунд/минут работы. Виснет наглухо — попытки убить ее любыми способами ни к чему не приводят. Она висит с одним потоком задедлоченым в ядре. Попытки смотреть на нее через Process Explorer 64 несколько раз приводили к BSOD, хотя конечно это может быть просто ошибка в ProcExp.


У меня не воспроизводится (Win7 SP1 64-bit, последние обновления установлены, антивируса/фаервола нет).
Прождал минут 15-20.

R>Видит ли кто-нибудь глупую ошибку в программе?


Сразу бросилось в глаза вот это:
HANDLE ct = (HANDLE)_beginthreadex(0, 0, client, (void*)addr.sin_port, 0, 0);
  if(ct == (HANDLE)-1)


_beginthreadex в случае ошибки возвращает NULL, а не -1.

http://msdn.microsoft.com/en-us/library/kdzttdcb(v=vs.90).aspx

...
_beginthreadex returns 0 on an error, in which case errno and _doserrno are set.

Хотя вряд ли ошибка в этом.
Re[2]: CancelIoEx вешает программу
От: remark Россия http://www.1024cores.net/
Дата: 29.07.13 18:11
Оценка:
Здравствуйте, okman, Вы писали:

O>Здравствуйте, remark, Вы писали:


R>>Следующая программа зависает через несколько секунд/минут работы. Виснет наглухо — попытки убить ее любыми способами ни к чему не приводят. Она висит с одним потоком задедлоченым в ядре. Попытки смотреть на нее через Process Explorer 64 несколько раз приводили к BSOD, хотя конечно это может быть просто ошибка в ProcExp.


O>У меня не воспроизводится (Win7 SP1 64-bit, последние обновления установлены, антивируса/фаервола нет).

O>Прождал минут 15-20.

R>>Видит ли кто-нибудь глупую ошибку в программе?


O>Сразу бросилось в глаза вот это:

O>
O>HANDLE ct = (HANDLE)_beginthreadex(0, 0, client, (void*)addr.sin_port, 0, 0);
O>  if(ct == (HANDLE)-1)
O>


O>_beginthreadex в случае ошибки возвращает NULL, а не -1.


O>http://msdn.microsoft.com/en-us/library/kdzttdcb(v=vs.90).aspx

O>

O>...
O>_beginthreadex returns 0 on an error, in which case errno and _doserrno are set.

O>Хотя вряд ли ошибка в этом.


Да, спасибо. Перепутал с _beginthread.
И, да, ошибка не в этом. Я видел, что потоки висят в WSAGetOverlappedResult.

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: CancelIoEx вешает программу
От: acDev Россия  
Дата: 29.07.13 19:10
Оценка:
R>Это минимальный репродьюсер проблемы из большой программы.

R>И, да, ошибка не в этом. Я видел, что потоки висят в WSAGetOverlappedResult.


По логике вызов CancelIoEx должен происходить только тогда, когда поле Internal структуры OVERLAPPED содержит 997 (WSA_IO_PENDING).
В вашем же когда это условие не выполняется.
Re[4]: CancelIoEx вешает программу
От: remark Россия http://www.1024cores.net/
Дата: 29.07.13 21:52
Оценка:
Здравствуйте, acDev, Вы писали:

R>>Это минимальный репродьюсер проблемы из большой программы.


R>>И, да, ошибка не в этом. Я видел, что потоки висят в WSAGetOverlappedResult.


D>По логике вызов CancelIoEx должен происходить только тогда, когда поле Internal структуры OVERLAPPED содержит 997 (WSA_IO_PENDING).

D>В вашем же когда это условие не выполняется.

Тогда я не понимаю, как потенциально CancelIoEx может отменять операции в других потоках -- основное назначение функции. Если IO происходит в одном потоке, а CancelIoEx — в другом, то завершение IO и CancelIoEx по определению происходят одновременно. Следовательно состояние OVERLAPPED может меняться из PENDING в "завершено".
Мое понимание, что CancelIoEx можно звать даже для уже завершенной оперции. В этом случае она возращает документированный код возврата ERROR_NOT_FOUND.

Если это не так, то как тогда вообще использовать CancelIoEx?

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[5]: CancelIoEx вешает программу
От: acDev Россия  
Дата: 30.07.13 06:42
Оценка:
R>Тогда я не понимаю, как потенциально CancelIoEx может отменять операции в других потоках -- основное назначение функции. Если IO происходит в одном потоке, а CancelIoEx — в другом, то завершение IO и CancelIoEx по определению происходят одновременно. Следовательно состояние OVERLAPPED может меняться из PENDING в "завершено".
R>Мое понимание, что CancelIoEx можно звать даже для уже завершенной оперции. В этом случае она возращает документированный код возврата ERROR_NOT_FOUND.

Да. Тут вы правы. Должна работать независимо от статуса операции.
Попробовал воспроизвести у себя — не получилось (10 минут на Win7 SP1 + all updates).

И как же этот алгоритм реализован под WinXP ?
Я бы лучше ввёл отдельный сигнал завершения PENDING-операций и использовал WaitForMultipleObject (проверено временем).
Re[6]: CancelIoEx вешает программу
От: acDev Россия  
Дата: 30.07.13 09:49
Оценка:
D>Попробовал воспроизвести у себя — не получилось (10 минут на Win7 SP1 + all updates).

Наврал! Воспроизводится в 100% случаев.

Если переписать код с правильным разбором ошибок (как написано в MSDN), то уже не воспроизводится:
  for(;;) {
    WSABUF b;
    b.buf = (char*)buf;
    b.len = recvbuf;
    DWORD recv = 0, flags = 0;
    int res = WSARecv(c, &b, 1, &recv, &flags, &ol, 0);
    if (res == 0) 
      break;
    if (res != SOCKET_ERROR)
      panic("WSARecv return NAN");
    DWORD dwErr = WSAGetLastError();
    if (dwErr != WSA_IO_PENDING)
      panic("WSARecv not PENDING");
    BOOL ret = WSAGetOverlappedResult(c, &ol, &recv, TRUE, &flags);
    if (!ret) {
      if(GetLastError() == WSA_OPERATION_ABORTED)
        break;
      panic("WSAGetOverlappedResult");
    }
  }
Re[6]: CancelIoEx вешает программу
От: remark Россия http://www.1024cores.net/
Дата: 30.07.13 10:25
Оценка:
Здравствуйте, acDev, Вы писали:

R>>Тогда я не понимаю, как потенциально CancelIoEx может отменять операции в других потоках -- основное назначение функции. Если IO происходит в одном потоке, а CancelIoEx — в другом, то завершение IO и CancelIoEx по определению происходят одновременно. Следовательно состояние OVERLAPPED может меняться из PENDING в "завершено".

R>>Мое понимание, что CancelIoEx можно звать даже для уже завершенной оперции. В этом случае она возращает документированный код возврата ERROR_NOT_FOUND.

D>Да. Тут вы правы. Должна работать независимо от статуса операции.

D>Попробовал воспроизвести у себя — не получилось (10 минут на Win7 SP1 + all updates).

D>И как же этот алгоритм реализован под WinXP ?

D>Я бы лучше ввёл отдельный сигнал завершения PENDING-операций и использовал WaitForMultipleObject (проверено временем).


Когда я снес антивирус AVG, проблема исчезла

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[7]: CancelIoEx вешает программу
От: remark Россия http://www.1024cores.net/
Дата: 30.07.13 10:36
Оценка:
Здравствуйте, acDev, Вы писали:

D>>Попробовал воспроизвести у себя — не получилось (10 минут на Win7 SP1 + all updates).


D>Наврал! Воспроизводится в 100% случаев.


D>Если переписать код с правильным разбором ошибок (как написано в MSDN), то уже не воспроизводится:

D>
D>  for(;;) {
D>    WSABUF b;
D>    b.buf = (char*)buf;
D>    b.len = recvbuf;
D>    DWORD recv = 0, flags = 0;
D>    int res = WSARecv(c, &b, 1, &recv, &flags, &ol, 0);
D>    if (res == 0) 
D>      break;
D>    if (res != SOCKET_ERROR)
D>      panic("WSARecv return NAN");
D>    DWORD dwErr = WSAGetLastError();
D>    if (dwErr != WSA_IO_PENDING)
D>      panic("WSARecv not PENDING");
D>    BOOL ret = WSAGetOverlappedResult(c, &ol, &recv, TRUE, &flags);
D>    if (!ret) {
D>      if(GetLastError() == WSA_OPERATION_ABORTED)
D>        break;
D>      panic("WSAGetOverlappedResult");
D>    }
D>  }
D>


А в чем принципиальное отличие от моей версии?


if (res == 0)
break;

0 значит, что операция завершилась синхронно, при этом не надо выходить из цикла. Это аналогично WSA_IO_PENDING.
Однако вроде это не должно вешать программу, тк все равно зовем closesocket.

А AVG случаем не установлен?

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[7]: CancelIoEx вешает программу
От: о_О
Дата: 30.07.13 10:52
Оценка:
Здравствуйте, remark, Вы писали:

R>Когда я снес антивирус AVG, проблема исчезла

R>

AVG — плохой антивирус и кривое ПО. Лучше не использовать его вообще
Re: CancelIoEx вешает программу
От: Аноним  
Дата: 30.07.13 11:35
Оценка:
Угадаю-ка?
Нет ли антивируса на машине, какого-нибудь второсортного, типа аваста ( верю, что симантек осилил бы установку Cancel routine )?

И общий совет щито делать в таких случаях:
надо настроить ручную генерацию дампа памяти и в момент зависания сгенерировать его.
ну а потом призвать шамана с windbg — он все скажет.
Re[2]: CancelIoEx вешает программу
От: remark Россия http://www.1024cores.net/
Дата: 30.07.13 11:44
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Угадаю-ка?

А>Нет ли антивируса на машине, какого-нибудь второсортного, типа аваста ( верю, что симантек осилил бы установку Cancel routine )?

http://www.rsdn.ru/forum/winapi/5245812.1
Автор: remark
Дата: 30.07.13



А>И общий совет щито делать в таких случаях:

А>надо настроить ручную генерацию дампа памяти и в момент зависания сгенерировать его.
А>ну а потом призвать шамана с windbg — он все скажет.

Дампа процесса? Или какой-то ядерный дамп всей памяти?
А где такого шамана найти?

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[8]: CancelIoEx вешает программу
От: acDev Россия  
Дата: 30.07.13 12:05
Оценка:
R>А AVG случаем не установлен?

Установлен "Антивирус Касперского 6.0.4.1611 для Windows Workstations".
Версия klif.sys 8.2.0.169 (2012-06-08).

Но у меня зависает не наглухо. Консольное окошко на всё реагирует, кроме как Alt+F4 и Ctrl+C (через TaskMgr'ы тоже не киляется). Но если после нажатия Alt+F4 подождать 5..15 минут, то процесс завершается.
Re[3]: CancelIoEx вешает программу
От: Аноним  
Дата: 30.07.13 14:27
Оценка: 6 (1)
R>Дампа процесса? Или какой-то ядерный дамп всей памяти?
http://msdn.microsoft.com/en-us/library/windows/hardware/ff545499(v=vs.85).aspx

R>А где такого шамана найти?

бывают...

на самом деле в данном случае все бы решилось довольно просто:
!process 0 0 myprocess.exe -> смотрим стеки своей прожки, так как она на убиении зависла, обычно найдется один только поток, для которого можно узнать его очередь ВВ ( там буквы IRP будут и всякие цифры )
!irp address -> увидим стек драйверов обрабатывающих это запрос и скорее всего увидим, что кто то держит запрос не установив для него Cancel Routine
делаем lmvm для модуля этого драйвера
гуглим что за зверь и обновляем/удаляем
минут на 10 работы
Re[9]: CancelIoEx вешает программу
От: remark Россия http://www.1024cores.net/
Дата: 04.08.13 16:58
Оценка:
Здравствуйте, acDev, Вы писали:

R>>А AVG случаем не установлен?


D>Установлен "Антивирус Касперского 6.0.4.1611 для Windows Workstations".

D>Версия klif.sys 8.2.0.169 (2012-06-08).

D>Но у меня зависает не наглухо. Консольное окошко на всё реагирует, кроме как Alt+F4 и Ctrl+C (через TaskMgr'ы тоже не киляется). Но если после нажатия Alt+F4 подождать 5..15 минут, то процесс завершается.


У меня так же висло.
5 минут — это похоже какой-то внутренний таймаут в ОС как раз для таких ситуаций.

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.