Что не так с этим вызовом Windows API WaitForSingleObject?
Процесс нестабильно завис в Windows 7. Я использую !analyze -v
команда в WinDbg
для анализа исключений. Это рассказывает ниже информацию. Исключение фактически выбрасывается WaitForSingleObject
функция, которая вызывается IrsSim!IrsNet_BlockOutput
, Анализ исключений WinDbg сказал мне, что это было INVALID_POINTER_READ
ошибка.
Для вызывающего кода pChannel->hMutex
не является NULL
, Я уже сбросил его и проверил его значение.
IRSNETRET IrsNet_BlockOutput( IRSNET *pChannel)
{
// Check channel
IRSNET_CHECK_CHANNEL(pChannel);
// Wait for synchronization mutex
switch(WaitForSingleObject(pChannel->hMutex, INFINITE))
{
...
}
<<<<< ==========
FAULTING_IP: IrsSim! Channel:: SendIrsMessage + 285 [s: \ som5 \ ics \ scsv \ isv \ test.u \ irssim \ irsiftransport.cpp @ 539] 00520ed5 8b06 mov eax, dword ptr [esi]
EXCEPTION_RECORD: ffffffff - (.exr 0xffffffffffffffff) ExceptionAddress: 77db4639 (ntdll! RtlDeactivateActivationContextUnsafeFast + 0x00000058)
ExceptionCode: c0150010 ExceptionFlags: 00000001 NumberParameters: 3 Параметр [0]: 00000000 Параметр [1]: 07befc58 Параметр [2]: 00000000DEFAULT_BUCKET_ID: INVALID_POINTER_READ
PROCESS_NAME: IrsSim.exe
ERROR_CODE: (NTSTATUS) 0xc0150010 - Деактивированный контекст активации не активен для текущего потока выполнения.
EXCEPTION_CODE: (NTSTATUS) 0xc0150010 - Деактивированный контекст активации не активен для текущего потока выполнения.
EXCEPTION_PARAMETER1: 00000000
EXCEPTION_PARAMETER2: 07befc58
EXCEPTION_PARAMETER3: 00000000
STACK_TEXT:!!!! 07d2fce0 00520ed5 irssim канал::SendIrsMessage+0x285 07d2fd1c 00521072 irssim CChannelArray::SendIrsMessage+0x132 07d2fd50 0052208a irssim CNetLibInterface::SendIrsMessage+0xBA 07d2fd78 005c01b6 irssim CSendActivity::Execute+0x76 07d2fdac 005e0b3f irssim SimulationThreadState::ExecuteOneActivity+0x11f 07d2fdf8 005cc937 irssim!CSimulationSubThreadState::ExecuteState+0x267 07d2fe8c 005ccf02 irssim!ThreadFctSubSimulation+0xf2 07d2fec4 73b1e3ee mfc90u!_AfxThreadEntry+0xf2 07d2ff4c 739f3433 msvcr90!_endthreadex+0x44 07d2ff84 739f34c7 msvcr90!_endthreadex+0xd8 07d2ff90 767d339a kernel32!BaseThreadInitThunk+0xE 07d2ff9c 77d69ed2 Ntdll! __ RtlUserThreadStart + 0x70 07d2ffdc 77d69ea5 ntdll! _RtlUserThreadStart + 0x1b
================================
После этого я использую команду! Teb, чтобы попытаться получить больше информации о стеке.
0: 011> к L=07beec2c 100 ChildEBP RetAddr 07bef54c 76be0bdd Ntdll NtWaitForMultipleObjects+0x15 07bef5e8 767d1a2c KERNELBASE WaitForMultipleObjectsEx+0x100 07bef630 767d4208 kernel32 WaitForMultipleObjectsExImplementation+0xE0 07bef64c 767f80a4 kernel32 WaitForMultipleObjects+0x18 07bef6b8 767f7f63 Kernel32 WerpReportFaultInternal+0x186 07bef6cc 767f7858 kernel32!!!!! WerpReportFault+0x70 07bef6dc 767f77d7 kernel32!BasepReportFault+0x20 07bef768 77da21d7 kernel32!UnhandledExceptionFilter+0x1af 07bef770 77da20b4 Ntdll!__RtlUserThreadStart+0x62 07bef784 77da1f59 Ntdll!_EH4_CallFilterFunc+0x12 07bef7ac 77d76ab9 Ntdll! _except_handler4 + 0x8e 07bef7d0 77d76a8b Ntdll! ExecuteHandler2 + 0x26 07bef7f4 77d76a2d Ntdll! ExecuteHandler + 0x24 07bef880 77 d40143 ntdll! RtlDispatchException + 0x127 07bef880 77db4639 ntdll! KiUserExceptionDispatcher + 0xf 07befc34 76be0ad7 ntdll! ObjectEx + 0xc3 07befcb0 767d1148 kernel32! WaitForSingleObjectExImplementation + 0x75
07befcc4 005e3b6e kernel32! WaitForSingleObject + 0x12
07befcd4 00520d3b IrsSim! IrsNet_BlockOutput + 0x1e
07befd14 00521072 IrsSim! Канал::SendIrsMessage+0xeb 07befd48 0052208a IrsSim!CChannelArray::SendIrsMessage+0x132 07befd70 005c01b6 IrsSim!CNetLibInterface::SendIrsMessage+0xBA 07befda4 005e0b3f IrsSim!CSendActivity::Execute+0x76 07befdf0 005cc937 IrsSim!SimulationThreadState::ExecuteOneActivity+0x11f 07befe84 005ccf02 IrsSim!CSimulationSubThreadState::ExecuteState+0x267 07befebc 73b1e3ee IrsSim!ThreadFctSubSimulation+0xf2 07beff44 739f3433 mfc90u!_AfxThreadEntry+0xf2 07beff7c 739f34c7 msvcr90!_endthreadex+0x44 07beff88 767d339a msvcr90!_endthreadex+0xd8 07beff94 77d69ed2 kernel32!BaseThreadInitThunk+0xE 07beffd4 77d69ea5 Ntdll! __ RtlUserThreadStart + 0x70 07beffec 00000000 ntdll! _RtlUserThreadStart + 0x1b
==================================== >>>>>>
4 ответа
Это похоже на исключение 0xC015000f, встречающееся в приложениях MFC ("Деактивируемый контекст активации не является последним активированным контекстом".)
Во всех случаях, когда я сталкивался с этим исключением, исключение не является основной проблемой. Это побочный эффект более раннего исключения, обычно нарушения прав доступа, когда стек не разматывается должным образом. Где-то кадр обработки, который использовал макрос, такой как макрос AFX_MANAGE_STATE, отсутствует в обработке исключений. В результате в следующий раз, когда контекстом активации манипулируют, скажем, с помощью другой процедуры, которая приводит к вызову чего-то вроде AFX_MAINTAIN_STATE2::~AFX_MAINTAIN_STATE2, система обнаруживает несоответствие файла cookie и выдает исключение.
В вашем случае вы можете вызывать исключение (скорее всего AV) в одном фрагменте кода, который затем проявляется в контексте исключения. Чтобы перехватить основную причину, запустите отладчик с включенной обработкой исключений первого шанса. Таким образом, AV, который захвачен в другом месте кадра вызова кем-то, возможно, использующим try/catch(...), будет выставлен. Поскольку вы, похоже, работаете с потоками, у вас может быть просто состояние гонки при доступе к памяти, которое вызывает основное исключение (если это действительно то, что происходит).
Я вижу в предыдущем посте: "На самом деле эта проблема возникает из-за переноса программы с 64-битной Win XP на 64-битную Win7. Поэтому компилятор переключается с VC6 на VC9".
Это не ошибка в MFC. MFC 6 не включает код переключения контекста активации (основанный на cookie), который был добавлен, я думаю, в Visual Studio 2005. Таким образом, вы не встретите это исключение. Мы также думали, что у более новой MFC были проблемы, но в каждом случае, с которым мы сталкивались, проблема была в нашем коде. Первоначальные проблемы маскируются потоками кода, которые начинались с try/catch(обычно...), который в конечном итоге вызывал код, который использовал один из макросов управления состоянием MFC, который затем вызывал больше кода, где в конечном итоге возникало AV. Так как перехват был наверху стека, и, в зависимости от повреждения, не все кадры разматываются должным образом, задняя сторона макросов MFC пропускается (некоторый деструктор не смог вытолкнуть свой контекст). Что еще хуже (для отладки), возможный сбой контекста может произойти где угодно в вашем коде (мы испытали многие из них в методе маршрутизации обработки сообщений в базовом окне CWnd). В конечном итоге мы создали еще один инструмент для запуска пользователя, который присоединялся бы как отладчик к нашему исполняемому файлу (цель выпуска), который перехватывал исключения первого шанса, и создавал файл dmp, чтобы мы могли найти начальную точку, где произошло исключение со времени сброса Контекстное исключение почти никогда не было полезным, так как первоначальный источник проблемы был давно выполнен.
Единственный способ, которым вызов может потерпеть неудачу таким образом, это если
pChannel->hMutex
является недействительным. Или pChannel
сам захвачен, или hMutex
, Скорее всего, первый.
Выглядит как проблема в деактивации контекста (мысли, основанные на дампе windbg). См. http://blogs.msdn.com/b/junfeng/archive/2006/03/19/sxs-activation-context-activate-and-deactivate.aspx статью.
Вы должны проверить, является ли дескриптор недействительным, а не просто NULL
лайк:
if (myHandle != INVALID_HANDLE_VALUE)
{
// do something
}
Обычно функция дескриптора create возвращает это значение в случае ошибки.