Re[11]: Исключение Access violation в WSASend и WSARecv (IOC
От: Gomes Россия http://irazin.ru
Дата: 02.07.09 10:13
Оценка:
Так, отставить. Со счетчиками мы тебе прогнали Ты же защищаешь не PerConnection, а PerIo. Тут железно: перед WSASend/WSARecv выделил, в обработчике удалил. Без вариантов. Так что какая-то бага изначально у тебя. Счетчики пока убирай — потом понадобятся.
Вот такой вопросик, чиста удостовериться: вот сюда "void HandleOperation(...)" указатель на CIOReq под каким именем передается? И что ты с ним делаешь?
Re[2]: Исключение Access violation в WSASend и WSARecv (IOCP
От: maxlosyam Россия  
Дата: 04.07.09 13:09
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Судя по этим строчкам, вы просто производите удаление объекта pIOReq, который же является OVERLAPPED структурой, до завершения асинхронной операции. А точно знать, что она завершилась, можно тогда, когда WSASend() вернула 0, или установилось событие hEvent из переданной OVERLAPPED структуры, или был бы вызван обработчик завершения lpCompletitionRoutine(), который бы устанавливался последним параметром WSASend(), но вы его не устанавливаете. Очевидно, до удаления указателя надо проверить код возврата и статус операции и, если она была отложенной, ждать события завершения...

А>=)

вообщето это к IOCP не относится, субж бы хотябы прочитали.
Re[12]: Исключение Access violation в WSASend и WSARecv (IOC
От: maxlosyam Россия  
Дата: 04.07.09 13:14
Оценка:
Здравствуйте, Аноним, Вы писали:

А>забыл добавить:


слушайте, а не могли бы вы привести декларацию класса CIOReq?
просто по первому посту все у вас нормально.
если валится на WSARecv не должно никак, не там ищете думаю.
Re[13]: Исключение Access violation в WSASend и WSARecv (IOC
От: Pepel Беларусь  
Дата: 06.07.09 12:07
Оценка:
главный вопрос здесь уже не частная конкретика иницииатора ветки полагаю, а тезис от Michael Chelnokov "асинхронная операция, инициируемая вызовом WSARecv/WSASend, может завершиться РАНЬШЕ и соответственно запись на IOCP о завершении мы можем получить РАНЬШЕ, чем сама функция WSARecv/WSASend вернет управление"

у меня данный расклад не учитывается, но и влеты в нарушения доступа к памяти единичные некие бывают таки

часть же коллег, сообщает, что такого быть не могеть , тот же Gomes "Обработчик вызывается только после завершения WSARecv/WSASend, иначе быть не может. "

вообщем мне все-таки странно осознавать, что в порт завершения ввода-вывода ставится запись о завершении асинхронной операции, в то время как ф-ция ее старта (WSARecv/WSASend) еще использует структуры асинхронного вызова, понятно, когда прапор орет "смирррна, круугггом " и он еще рот не закрыл , а все уже повернулись, но здесь ж думается трезвые люди писали концепт асинхроники этой всей ...

по итогу получается надо дорабатывать код и ставить защиту от такой вот особенности, так я понимаю ?
Re[14]: Исключение Access violation в WSASend и WSARecv (IOC
От: xentry  
Дата: 06.07.09 12:17
Оценка: +1
Здравствуйте, Pepel, Вы писали:

Все говорят об одном и том же разными словами.
P> тезис от Michael Chelnokov "асинхронная операция, инициируемая вызовом WSARecv/WSASend, может завершиться РАНЬШЕ и соответственно запись на IOCP о завершении мы можем получить РАНЬШЕ, чем сама функция WSARecv/WSASend вернет управление"
Он имеет ввиду что обработчик может начать выполняться в другом потоке раньше чем выполнится инструкция, следующая за WSARecv/WSASend

P>тот же Gomes "Обработчик вызывается только после завершения WSARecv/WSASend, иначе быть не может. "

Раньше чем началась операция WSARecv/WSASend началась обработчик вызван быть не может.
Re[15]: Исключение Access violation в WSASend и WSARecv (IOC
От: Pepel Беларусь  
Дата: 06.07.09 12:23
Оценка:
Здравствуйте, xentry, Вы писали:

>Он имеет ввиду что обработчик может начать выполняться в другом потоке раньше чем >выполнится инструкция, следующая за WSARecv/WSASend


это конечно .. значит я не так понял его пояснение, тогда все отлично, конечно же в мультизадачной среде это норма вещей
Re[14]: Исключение Access violation в WSASend и WSARecv (IOC
От: Gomes Россия http://irazin.ru
Дата: 06.07.09 12:30
Оценка: 2 (1)
Здравствуйте, Pepel, Вы писали:

P>Michael Chelnokov "асинхронная операция, инициируемая вызовом WSARecv/WSASend, может завершиться РАНЬШЕ и соответственно запись на IOCP о завершении мы можем получить РАНЬШЕ, чем сама функция WSARecv/WSASend вернет управление"

Правильно. Надо понимать, что внутри WSARecv/WSASend есть много кода. Теперь перечитываем верхнее. И принимаем как факт то, что после прихода завершения в обработчик, входные параметры этими функциями не используются, хотя возврат из них может ещё не произойти.
Т.е. для нас фактически получается:
P>Gomes "Обработчик вызывается только после завершения WSARecv/WSASend, иначе быть не может."

То, что где-то у кого-то что-то валится — это исключительно ошибки в коде.
Re[15]: Исключение Access violation в WSASend и WSARecv (IOC
От: Pepel Беларусь  
Дата: 06.07.09 12:52
Оценка:
Gomes,

спасибо.. полегчало, не очень хотелось синхронизацию еще свою отстраивать на этих делах
Re[16]: Исключение Access violation в WSASend и WSARecv (IOC
От: Аноним  
Дата: 06.07.09 16:10
Оценка:
Здравствуйте, Pepel, Вы писали:
P> спасибо.. полегчало, не очень хотелось синхронизацию еще свою отстраивать на этих делах
А я бы не стал верить ни уважаемому Гомесу, ни Микрософту.
Приведите пожалуйста выдержку из какого нибудь документа, где сказано, что операция WSASend/WSARecv выполняется атомарно по отношению к обработчику завершения?
На многоядерных машинах, да и еще в таком абсолютно непредсказуемом (по отношению к переключению контекста внутренних потоков) механизме, как IOCP, вполне можно ожидать, что обработчик может позваться еще до инструкции ret из WSASend/WSARecv.
И никто не даст гарантию, что после постановки запроса на выполнение операции и до выхода из WSASend/WSARecv данные функции ничего не делают с переданным в них буфером (там могут быть по крайней мере какие нибудь "невинные" проверки).
Самое интересное, по моим подсчетам, как минимум трое достаточно грамотных и опытных людей, сообщили о неких "ложных срабатываниях" и непонятных поломках то ли в дебаге, то ли еще где то.
Неужели это не повод перестраховаться?
Как говорится, лучше перебдеть, имхо.
Re[17]: Исключение Access violation в WSASend и WSARecv (IOC
От: Michael Chelnokov Украина  
Дата: 06.07.09 17:44
Оценка:
Здравствуйте, Аноним, Вы писали:

А>И никто не даст гарантию, что после постановки запроса на выполнение операции и до выхода из WSASend/WSARecv данные функции ничего не делают с переданным в них буфером (там могут быть по крайней мере какие нибудь "невинные" проверки).


Не, все проверки гарантировано заканчиваются до возникновения уведомления о завершении операции ввода/вывода. Это следует хотя бы из терминологии.
Re[17]: Исключение Access violation в WSASend и WSARecv (IOC
От: Gomes Россия http://irazin.ru
Дата: 07.07.09 05:46
Оценка:
Здравствуйте, Аноним, Вы писали:

А>А я бы не стал верить ни уважаемому Гомесу, ни Микрософту.

По вопросам веры — в церковь (с) Гоблин ;)

А>Приведите пожалуйста выдержку из какого нибудь документа, где сказано, что операция WSASend/WSARecv выполняется атомарно по отношению к обработчику завершения?

По-твоему они должны писать документ на любую бердовую мысль, которая может возникнуть у пользователя?

А>И никто не даст гарантию, что после постановки запроса на выполнение операции и до выхода из WSASend/WSARecv данные функции ничего не делают с переданным в них буфером (там могут быть по крайней мере какие нибудь "невинные" проверки).

Давай не надо ерунду писать.

А>Самое интересное, по моим подсчетам, как минимум трое достаточно грамотных и опытных людей, сообщили о неких "ложных срабатываниях" и непонятных поломках то ли в дебаге, то ли еще где то.

А на ошибки в компиляторе опытные люди не жаловались?

А>Неужели это не повод перестраховаться?

Да лучше в каске спать ;)

Без обид — но смешно читать.
Re: Исключение Access violation в WSASend и WSARecv (IOCP)
От: Аноним  
Дата: 09.07.09 08:57
Оценка:
Здравствуйте, Armastab, Вы писали:

A>Из всего вышеописанного у меня сложилось ощущение, что один из ожидающих рабочих потоков получает управление и сигнал о завершении ввода-вывода, еще до того как произошел возврат из WSASend WSARecv.

A>Он удаляет объект pIOReq и в WSASend/WSARecv происходит нарушение доступа.

A>Вопросы:

A>как сигнал о завершении ввода-вывода может поступать до завершения асинхронной функции ввода-вывода,
A>почему это исключение не отлавливается стандартными средствами обработки исключений
A>что с этим делать?

Вот Michael Chelnokov уже правильно все написал и не один раз
Конечно, вызов обработчика IO может быть раньше чем выход из WSASend/WSARecv и иже с ними
НО! С какого перепугу нужно грохать (и вообще чего-то делать) с Overlapped и иже с ним после успешного (такого, которое породит overlapped io) вызова асинхронной функции? Отдал системе кусок памяти — не трожь! Пока система не отдаст его обратно.
Варианта всего два:
или ваш вызов WSAxxx закончился и сказал об ошибке (события не будет) — делай со структурой все что хочется (удаляй, обнуляй, возвращай в пул структур...)
или все хорошо и будет событие — вот в нем и только в нем нужно и можно работать с этой структурой
и для этого никаких счетчиков и синхронизаторов не нужно
Re[2]: Исключение Access violation в WSASend и WSARecv (IOCP
От: Armastab  
Дата: 09.07.09 10:35
Оценка:
Здравствуйте, Аноним, Вы писали:

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


A>>Из всего вышеописанного у меня сложилось ощущение, что один из ожидающих рабочих потоков получает управление и сигнал о завершении ввода-вывода, еще до того как произошел возврат из WSASend WSARecv.

A>>Он удаляет объект pIOReq и в WSASend/WSARecv происходит нарушение доступа.

A>>Вопросы:

A>>как сигнал о завершении ввода-вывода может поступать до завершения асинхронной функции ввода-вывода,
A>>почему это исключение не отлавливается стандартными средствами обработки исключений
A>>что с этим делать?

А>Вот Michael Chelnokov уже правильно все написал и не один раз

А>Конечно, вызов обработчика IO может быть раньше чем выход из WSASend/WSARecv и иже с ними
А>НО! С какого перепугу нужно грохать (и вообще чего-то делать) с Overlapped и иже с ним после успешного (такого, которое породит overlapped io) вызова асинхронной функции? Отдал системе кусок памяти — не трожь! Пока система не отдаст его обратно.
А>Варианта всего два:
А>или ваш вызов WSAxxx закончился и сказал об ошибке (события не будет) — делай со структурой все что хочется (удаляй, обнуляй, возвращай в пул структур...)
А>или все хорошо и будет событие — вот в нем и только в нем нужно и можно работать с этой структурой
А>и для этого никаких счетчиков и синхронизаторов не нужно

Возможно, я не совсем понятно написал, но в реальности у меня Overlapped (он же CIOReq) после вызова асинхронной операции не грохается, эта структура удаляеся только в обработчике HandleOperation. По всем наблюдаемым признакам ситуация именно такая как описывает Michael Chelnokov — вызов обработчика происходит, до возврата из асинхронной операции WSARecv/WSASend. Но я все еще не исключаю багов в коде, о которых говорит Gomes.
Re[12]: Исключение Access violation в WSASend и WSARecv (IOC
От: Armastab  
Дата: 09.07.09 10:59
Оценка:
Здравствуйте, Gomes, Вы писали:

G>Так, отставить. Со счетчиками мы тебе прогнали Ты же защищаешь не PerConnection, а PerIo. Тут железно: перед WSASend/WSARecv выделил, в обработчике удалил. Без вариантов. Так что какая-то бага изначально у тебя. Счетчики пока убирай — потом понадобятся.

G>Вот такой вопросик, чиста удостовериться: вот сюда "void HandleOperation(...)" указатель на CIOReq под каким именем передается? И что ты с ним делаешь?

Вкратце, функция Run рабочего потока выглядит так (проверки ошибок GetLastError и т.д. для краткости вырезаны):

while(true)
{

OVERLAPPED* pov(NULL);

fOk = m_refIOCP.GetStatus(&CompKey,&dwNumBytes, (OVERLAPPED**)&pov);

pIOReq = static_cast<CIOReq*>(pov);

if (fOk) {

if(CompKey == 0)
break;

HandleOperation(CompKey, pIOReq, dwNumBytes);
}

delete pIOReq;

}


В HandleOperation проверяется тип операции pIOReq и создаются новые асинхронные вызовы с другими экземплярами CIOReq, при это исходный pIOReq нигде внутри HandleOperation не модифицируется. Вышеприведенный delete это единственное место уничтожения структуры CIOReq/
Re[3]: Исключение Access violation в WSASend и WSARecv (IOCP
От: Аноним  
Дата: 09.07.09 14:09
Оценка:
Здравствуйте, Armastab, Вы писали:

A>Здравствуйте, Аноним, Вы писали:


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


A>>>Из всего вышеописанного у меня сложилось ощущение, что один из ожидающих рабочих потоков получает управление и сигнал о завершении ввода-вывода, еще до того как произошел возврат из WSASend WSARecv.

A>>>Он удаляет объект pIOReq и в WSASend/WSARecv происходит нарушение доступа.

A>>>Вопросы:

A>>>как сигнал о завершении ввода-вывода может поступать до завершения асинхронной функции ввода-вывода,
A>>>почему это исключение не отлавливается стандартными средствами обработки исключений
A>>>что с этим делать?

А>>Вот Michael Chelnokov уже правильно все написал и не один раз

А>>Конечно, вызов обработчика IO может быть раньше чем выход из WSASend/WSARecv и иже с ними
А>>НО! С какого перепугу нужно грохать (и вообще чего-то делать) с Overlapped и иже с ним после успешного (такого, которое породит overlapped io) вызова асинхронной функции? Отдал системе кусок памяти — не трожь! Пока система не отдаст его обратно.
А>>Варианта всего два:
А>>или ваш вызов WSAxxx закончился и сказал об ошибке (события не будет) — делай со структурой все что хочется (удаляй, обнуляй, возвращай в пул структур...)
А>>или все хорошо и будет событие — вот в нем и только в нем нужно и можно работать с этой структурой
А>>и для этого никаких счетчиков и синхронизаторов не нужно

A>Возможно, я не совсем понятно написал, но в реальности у меня Overlapped (он же CIOReq) после вызова асинхронной операции не грохается, эта структура удаляеся только в обработчике HandleOperation. По всем наблюдаемым признакам ситуация именно такая как описывает Michael Chelnokov — вызов обработчика происходит, до возврата из асинхронной операции WSARecv/WSASend. Но я все еще не исключаю багов в коде, о которых говорит Gomes.


ну все просто
1) создал (достал из пула) структуру Overlapped с "хвостом"
2) передал в, скажем, WSARecv()
3) проверил возврат, ноль или не ноль и ERROR_IO_PENDING — значит жди события на IOCP
иначе грохай структуру (возвращай в пул)
Примечание: в момент проверки кода возврата, в случае безошибочности, событие может уже и наступить и быть обработанным, но, поскольку, ответ будет положительным то ничего со структурой делать нельзя — она отдана обработчику, ну а если ошибка, то в момент проверки мы точно знаем что события не наступило и не наступит, и со структурой можно что-то делать
4) в обработчике события обрабатывай структуру и код ошибки а затем грохай структуру (возвращай в пул)
Re[4]: Исключение Access violation в WSASend и WSARecv (IOCP
От: Armastab  
Дата: 09.07.09 17:38
Оценка:
Здравствуйте, Аноним, Вы писали:

А>ну все просто

А>1) создал (достал из пула) структуру Overlapped с "хвостом"
А>2) передал в, скажем, WSARecv()
А>3) проверил возврат, ноль или не ноль и ERROR_IO_PENDING — значит жди события на IOCP
А>иначе грохай структуру (возвращай в пул)
А>Примечание: в момент проверки кода возврата, в случае безошибочности, событие может уже и наступить и быть обработанным, но, поскольку, ответ будет положительным то ничего со структурой делать нельзя — она отдана обработчику, ну а если ошибка, то в момент проверки мы точно знаем что события не наступило и не наступит, и со структурой можно что-то делать
А>4) в обработчике события обрабатывай структуру и код ошибки а затем грохай структуру (возвращай в пул)

Именно так я все и делал, только не использовал пул, а создавал/разрушал. Именно в такой ситуации и возникала, та самая "странная" ошибка .
Re[13]: Исключение Access violation в WSASend и WSARecv (IOC
От: xentry  
Дата: 10.07.09 10:13
Оценка:
Здравствуйте, Armastab, Вы писали:

A>Вкратце, функция Run рабочего потока выглядит так (проверки ошибок GetLastError и т.д. для краткости вырезаны):


Можешь сделать минимальный тест-кейс в котором проблема воспроизводиться? Имхо это стоит потраченного времени. Иначе этот топик все больше становится похож на выездное заседание телепатов.
Re[5]: Исключение Access violation в WSASend и WSARecv (IOCP
От: Аноним  
Дата: 10.07.09 14:37
Оценка:
Здравствуйте, Armastab, Вы писали:

A>Здравствуйте, Аноним, Вы писали:


А>>ну все просто

А>>1) создал (достал из пула) структуру Overlapped с "хвостом"
А>>2) передал в, скажем, WSARecv()
А>>3) проверил возврат, ноль или не ноль и ERROR_IO_PENDING — значит жди события на IOCP
А>>иначе грохай структуру (возвращай в пул)
А>>Примечание: в момент проверки кода возврата, в случае безошибочности, событие может уже и наступить и быть обработанным, но, поскольку, ответ будет положительным то ничего со структурой делать нельзя — она отдана обработчику, ну а если ошибка, то в момент проверки мы точно знаем что события не наступило и не наступит, и со структурой можно что-то делать
А>>4) в обработчике события обрабатывай структуру и код ошибки а затем грохай структуру (возвращай в пул)

A>Именно так я все и делал, только не использовал пул, а создавал/разрушал. Именно в такой ситуации и возникала, та самая "странная" ошибка .


тогда стратегически все верно, ищи ошибку в коде
Re[6]: Исключение Access violation в WSASend и WSARecv (IOCP
От: maxlosyam Россия  
Дата: 10.07.09 15:01
Оценка: 2 (1)
Здравствуйте, Аноним, Вы писали:

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


A>>Здравствуйте, Аноним, Вы писали:


А>>>ну все просто

А>>>1) создал (достал из пула) структуру Overlapped с "хвостом"
А>>>2) передал в, скажем, WSARecv()
А>>>3) проверил возврат, ноль или не ноль и ERROR_IO_PENDING — значит жди события на IOCP
А>>>иначе грохай структуру (возвращай в пул)
А>>>Примечание: в момент проверки кода возврата, в случае безошибочности, событие может уже и наступить и быть обработанным, но, поскольку, ответ будет положительным то ничего со структурой делать нельзя — она отдана обработчику, ну а если ошибка, то в момент проверки мы точно знаем что события не наступило и не наступит, и со структурой можно что-то делать
А>>>4) в обработчике события обрабатывай структуру и код ошибки а затем грохай структуру (возвращай в пул)

A>>Именно так я все и делал, только не использовал пул, а создавал/разрушал. Именно в такой ситуации и возникала, та самая "странная" ошибка .


А>тогда стратегически все верно, ищи ошибку в коде


вот ещё раз прошу, показать декларацию CIOReq, помоему грохаться может из-за того что, что-то не то с этим классом.
возможные варианты
1. класс неунаследован от OVERLAPPED )) ну это врядли, потому что детский сад
2. класс унаследован от OVERLAPPED, но OVERLAPPED не первый в списке.
3. структура OVERLAPPED не обнуляется перед использованием, точно не скажу надо ли оно, но у меня в проекте обнуляется, это надо спросить кто точно химичил с обнулением, и как оно влияет на это.
4. CIOReq гдето reinterpret_cast'ируется в какойнибудь родительский класс, вместо static_cast'a. ну это так мысля в слух, как пример того что гдето OVERLAPPED коцается.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.