Что может быть причиной этого сбоя в libzmq.dll?

У меня есть приложение x64 C#, работающее на .NET Framework 4.0 x64, в котором используется clrzmq-x64. 2.2.2 (от NuGet) для ZeroMQ.

Он работает нормально, когда я его отлаживаю (например, F5), но он отправляет только около 30 сообщений в секунду. Если я не подключаю отладчик (например, CTRL-F5), он обрабатывает более 1000 сообщений в секунду... но падает примерно через 30 секунд.

У меня возникли проблемы с диагностикой проблемы, потому что точка, в которой происходит сбой, отсутствует в моем коде.

Я вставил всю информацию, которую смог найти, которая может оказаться полезной, но я изо всех сил пытаюсь понять, как интерпретировать трассировку стека.

Журнал событий:

Faulting application name: MyApplication.exe, version: 1.0.0.0, time stamp: 0x4f5a05b3
Faulting module name: MSVCR100.dll, version: 10.0.40219.325, time stamp: 0x4df2bcac
Exception code: 0x40000015
Fault offset: 0x00000000000761c9
Faulting process id: 0x273c
Faulting application start time: 0x01ccfdf8acdc087e
Faulting application path: [path redacted]\MyApplication.exe
Faulting module path: C:\Windows\system32\MSVCR100.dll
Report Id: f3518caf-69eb-11e1-9ed1-50e549e1c0d9

Трассировка стека:

msvcr100.dll!__crt_debugger_hook()  
msvcr100.dll!_call_reportfault()  + 0x124 bytes 
msvcr100.dll!abort()  + 0x35 bytes  
libzmq.dll!zmq::signaler_t::make_fdpair(unsigned __int64 * r_=0x000000002c557ee0, unsigned __int64 * w_=0x000007feedcb7ad2)  Line 263   C++
libzmq.dll!zmq::signaler_t::signaler_t()  Line 80   C++
libzmq.dll!zmq::mailbox_t::mailbox_t()  Line 26 + 0x17 bytes    C++
libzmq.dll!zmq::socket_base_t::socket_base_t(zmq::ctx_t * parent_=0x0000000027e3e470, unsigned int tid_=4294967294)  Line 124 + 0x6b bytes  C++
libzmq.dll!zmq::push_t::push_t(zmq::ctx_t * parent_=0x0000000076e3e3db, unsigned int tid_=0)  Line 30 + 0xe bytes   C++
libzmq.dll!zmq::socket_base_t::create(int type_=43532552, zmq::ctx_t * parent_=0x0000000002984130, unsigned int tid_=43532512)  Line 100 + 0x29 bytes   C++
libzmq.dll!zmq::ctx_t::create_socket(int type_=489832384)  Line 184 + 0xe bytes C++
clr.dll!DoNDirectCall__PatchGetThreadCall()  + 0x7b bytes   
000007ff00168461()  
000007ff0016833f()  
000007ff00166b22()  
000007ff00166997()  
mscorlib.ni.dll!000007fef4669e70()  
[Frames below may be incorrect and/or missing, no symbols loaded for mscorlib.ni.dll]   
00000000030bd4c0()  
0000000027e3e9c8()  
mscorlib.ni.dll!000007fef4094568()  
clr.dll!JIT_IsInstanceOfAny()  + 0x20 bytes 
mscorlib.ni.dll!000007fef465e56b()  
00000000030bd560()  
00000000006f8d10()

person Tom Robinson    schedule 09.03.2012    source источник


Ответы (2)


Это https://github.com/zeromq/libzmq/pull/491.

По сути, в загруженной системе Windows, в которой часто создается и уничтожается много сокетов ZMQ, создание сокета подразумевает создание пары внутренних сокетов, и это может привести к сбою с тем же стеком, который вы показали выше. Что еще хуже, в сборке без отладки исключение приводит к тому, что код создания сокета отказывается от занятого критического раздела, что затем приводит к тому, что последующие попытки создания сокета зависают навсегда.

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

person Gabriele Giuseppini    schedule 05.04.2013
comment
Исправление работает, как и ожидалось. Мы больше не видим этих сбоев при создании сокетов, а также мы не видим, чтобы create_socket зависал навсегда после этого. - person Gabriele Giuseppini; 08.04.2013

Возможно ли, что вы все время создаете новые сокеты? В этом случае попробуйте настроить контекст и сокеты один раз и использовать их повторно.

person mgoetzke    schedule 10.03.2012
comment
Я использую общий контекст, но создаю несколько сокетов в разных задачах. Если я разделяю сокет, то REQ/REP с сообщениями в фреймах не работает, потому что одна задача может пытаться отправить () или SendMore () в этом сокете, в то время как другая вызывает Recv (). Думаю, мне нужен способ ограничить сокеты пулом, чтобы я не превышал этот предел. - person Tom Robinson; 10.03.2012