CSocket:: Создать исключение броска в моем приложении MFC
У меня приложение (VC MFC) запущено с gflags с включенной Pageheap для отслеживания повреждения кучи страниц.
Теперь приложение потерпело крах, и оно показывает эту ошибку, я не мог интерпретировать эти строки (кроме ощущения недоступности ресурса)
Может кто-нибудь пролить свет на то, что именно является причиной, вызвавшей сбой приложения?
(информация: приложение является многопоточным, около 500 запущенных потоков на многопроцессорной машине)
kernel32!RaiseException+53
msvcrt!_CxxThrowException+36
mfc42u!AfxThrowResourceException+19
mfc42u!AfxRegisterWndClass+ab
mfc42u!CAsyncSocket::AttachHandle+5c
mfc42u!CAsyncSocket::Socket+25
mfc42u!CAsyncSocket::Create+14
3 ответа
Эта та же самая проблема свела меня с ума, но, наконец, я исправил ее, и она работает. Это ошибка с библиотекой сокетов MFC, которая в потоке [кроме основного потока приложения], если мы пытаемся сделать что-то вроде
CSocket socket;
socket.Create();
Это вызовет необработанное исключение. Я нашел статью об этом Посмотрите, что Microsoft говорит об этом
что-то говорило из Microsoft, но это мне тоже не помогло. Итак, вот обходной путь, который я нашел, и я надеюсь, что он может помочь таким разочарованным парням, как я.
Внутри нити, сделайте это
CSocket mySock;
SOCKET sockethandle = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
mySock.m_hSocket= sockethandle;
После этого НЕ вызывайте mySock.Create, так как он был создан уже через присвоение дескриптора сокета. Я не уверен, что мы можем использовать mySock.Attach (sockethandle), поскольку я еще не пробовал.
После этого вы можете позвонить Connect и т. Д. Напрямую.
Когда вы закончите с использованием сокета, НЕ звоните mySock.Close()
- скорее позвони closesocket(mySock.m_hSocket);
И это освободит объект сокета. Если Attach работает в вышеупомянутом случае, то я думаю, что нам нужно сделать Detach здесь, когда освободить сокет.
Удачи
У меня была та же проблема, и после многих попыток я заметил следующую ссылку CAsyncSocket:
Создание не является потокобезопасным. Если вы вызываете его в многопоточной среде, где он может вызываться одновременно разными потоками, обязательно защищайте каждый вызов мьютексом или другой блокировкой синхронизации.
После добавления синхронизации Mutex он больше не выдает исключение.
Интересно, действительно ли это ваша проблема с повреждением кучи, или ваша программа только что столкнулась с ограничением ресурсов в результате работы с Pageheap.
Я не могу вспомнить точные детали, но Pageheap влечет за собой дополнительные накладные расходы памяти, настолько, что вы можете исчерпать память гораздо раньше, чем без включения Pageheap.
При 500 запущенных потоках у вас есть стек по 1 МБ для каждого, плюс любая память, которую они динамически распределяли по пути.
CAsyncSocket::AttachHandle
триггеры AfxThrowResourceException
если он не может создать окно. Кажется, что ваша система насыщена из-за Pageheap.
Нужно ли иметь 500 запущенных потоков, чтобы воспроизвести проблему? Возможно, если бы вы могли немного снизить этот показатель, было бы больше доступных ресурсов.