这个Windows API调用WaitForSingleObject有什么问题?

时间:2012-05-23 08:55:01

标签: c++ windows exception windbg activation-context-api

该过程在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!频道:: 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)   异常地址:77db4639   (NTDLL!RtlDeactivateActivationContextUnsafeFast + 0x00000058)
  ExceptionCode:c0150010 ExceptionFlags:00000001 NumberParameters:3   参数[0]:00000000参数[1]:07befc58参数[2]:   00000000

     

DEFAULT_BUCKET_ID:INVALID_POINTER_READ

     

PROCESS_NAME:IrsSim.exe

     

ERROR_CODE:(NTSTATUS)0xc0150010 - 激活上下文正在   对于当前执行的线程,deactivated不活动。

     

EXCEPTION_CODE:(NTSTATUS)0xc0150010 - 激活上下文正在   对于当前执行的线程,deactivated不活动。

     

EXCEPTION_PARAMETER1:00000000

     

EXCEPTION_PARAMETER2:07befc58

     

EXCEPTION_PARAMETER3:00000000

     

STACK_TEXT:07d2fce0 00520ed5 irssim!Channel :: 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〕 k 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 77d40143 ntdll!RtlDispatchException + 0x127 07bef880 77db4639   ntdll!KiUserExceptionDispatcher + 0xf 07befc34 76be0ad7   ntdll!RtlDeactivateActivationContextUnsafeFast + 0x58 07befc38 76be0abc   KERNELBASE!WaitForSingleObjectEx + 0xde 07befc98 767d1194   KERNELBASE!WaitForSingleObjectEx + 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

     

====================================>>>>>&GT ;

4 个答案:

答案 0 :(得分:3)

这看起来很像MFC应用程序中遇到的0xC015000f异常(“停用的激活上下文不是最近激活的激活上下文。”)

在我遇到此异常的所有情况下,异常都不是主要问题。它是早期异常的副作用,通常是访问冲突,其中堆栈未正确展开。某处使用宏(例如AFX_MANAGE_STATE宏)的调用帧在异常处理中被遗漏。结果是下次操作激活上下文时,例如另一个导致调用AFX_MAINTAIN_STATE2 :: ~AFX_MAINTAIN_STATE2之类的例程,系统会检测到cookie不匹配并抛出异常。

在您的情况下,您可能会在一段代码中导致异常(很可能是AV),然后由上下文异常表明。要捕获根本原因,请在启用第一次机会异常处理的情况下运行调试器。这样,可能会使用try / catch(...)的某个人在调用帧的其他地方被捕获的AV将被暴露。由于您似乎是线程,因此您可能只是在内存访问上遇到一个竞争条件导致主要异常(如果确实发生了这种情况)。

我在上一篇文章中看到: “事实上,这个问题来自于将程序从64位Win XP移植到64位Win7。因此编译器从VC6切换到VC9。”

这不是MFC中的错误。 MFC 6不包括在Visual Studio 2005中添加的激活上下文切换代码(基于cookie)。因此,您不会遇到此异常。我们也认为较新的MFC存在问题,但在我们遇到的每种情况下,都是我们的代码导致了问题。原始问题被代码流掩盖,代码流以try / catch(通常是......)开始,最终调用代码使用其中一个MFC管理状态宏,然后调用更多代码,最终AV将发生。由于捕获是向上堆栈,并且取决于损坏,并非所有帧都被正确解开,MFC宏的背面被遗漏(一些析构函数无法弹出其上下文)。更糟糕的是(对于调试),最终的上下文崩溃可能发生在代码中的任何地方(我们在CWnd的基本窗口消息处理路由方法中经历了很多)。我们最终为用户创建了另一个工具,它将自己作为调试器附加到我们的(释放目标)可执行文件中,该可执行文件捕获了第一次机会异常并创建了一个dmp文件,因此我们可以找到自从转储之后发生异常的初始点。上下文异常几乎从来没有用过,因为问题的原始来源早于执行过去。

答案 1 :(得分:2)

呼叫以这种方式失败的唯一方法是

pChannel->hMutex

无效。 pChannel本身都是invaild,或hMutex。很可能是前者。

答案 2 :(得分:1)

您应该检查句柄是否无效,而不仅仅是NULL

if (myHandle != INVALID_HANDLE_VALUE)
{
    // do something
}

如果出现错误,通常create handle函数将返回此值。

答案 3 :(得分:1)

在上下文停用时看起来像问题(基于windbg转储的想法)。请参阅http://blogs.msdn.com/b/junfeng/archive/2006/03/19/sxs-activation-context-activate-and-deactivate.aspx文章。