【问题标题】:Windows C++ app error in WaitForSingleObjectWaitForSingleObject 中的 Windows C++ 应用程序错误
【发布时间】:2011-01-31 15:56:57
【问题描述】:

我有一个在 Windows Server 2003 上运行的 C++ 多线程应用程序,它每隔几天就会崩溃一次。通过windbg运行崩溃,我得到以下结果:

FAULTING_IP: 
+2502faf01a7df58
00000000 ??              ???

EXCEPTION_RECORD:  ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 00000000
   ExceptionCode: 80000003 (Break instruction exception)
  ExceptionFlags: 00000000
NumberParameters: 0

FAULTING_THREAD:  00001520

DEFAULT_BUCKET_ID:  STATUS_BREAKPOINT

PROCESS_NAME:  FixFastMDP.exe

ERROR_CODE: (NTSTATUS) 0x80000003 - {EXCEPTION}  Breakpoint  A breakpoint has been reached.

EXCEPTION_CODE: (HRESULT) 0x80000003 (2147483651) - One or more arguments are invalid

MOD_LIST: <ANALYSIS/>

NTGLOBALFLAG:  0

APPLICATION_VERIFIER_FLAGS:  0

PRIMARY_PROBLEM_CLASS:  STATUS_BREAKPOINT

BUGCHECK_STR:  APPLICATION_FAULT_STATUS_BREAKPOINT

LAST_CONTROL_TRANSFER:  from 7c827d0b to 7c8285ec

STACK_TEXT:  
0293ee78 7c827d0b 77e61d1e 00000484 00000000 ntdll!KiFastSystemCallRet

0293ee7c 77e61d1e 00000484 00000000 0293eec0 ntdll!NtWaitForSingleObject+0xc

0293eeec 77e61c8d 00000484 00001388 00000000 kernel32!WaitForSingleObjectEx+0xac

0293ef00 00403bce 00000484 00001388 108744c3 kernel32!WaitForSingleObject+0x12

0293feec 7c83a827 0159ba50 7c889080 0016b278 FixFastMDP!decoderItThread+0x7e 
[c:\gszdvmt\trading\serverside\globex\fixfastmdp\mdpmulticast.cpp @ 732]

0293ff44 7c83aa0b 00403b50 0159ba50 00000000 ntdll!RtlpWorkerCallout+0x71

0293ff64 7c83aa82 00000000 0159ba50 0016b278 ntdll!RtlpExecuteWorkerRequest+0x4f

0293ff78 7c839f60 7c83a9ca 00000000 0159ba50 ntdll!RtlpApcCallout+0x11

0293ffb8 77e64829 00000000 00000000 00000000 ntdll!RtlpWorkerThread+0x61

0293ffec 00000000 7c839efb 00000000 00000000 kernel32!BaseThreadStart+0x34



STACK_COMMAND:  ~0s; .ecxr ; kb

FOLLOWUP_IP: 
FixFastMDP!decoderItThread+7e [c:\gszdvmt\trading\serverside\globex\fixfastmdp\mdpmulticast.cpp @ 732]
00403bce 3d02010000      cmp     eax,102h

FAULTING_SOURCE_CODE:  
   728:         ////

   729:         // call the decoderit() func with the message

   730:         DWORD waitError = WaitForSingleObject( FFDecoderMutex, MUTEX_TIMEOUT );

   731:         {

>  732:             if( waitError == WAIT_TIMEOUT )

   733:             {

   734:                 logMsg( "[decoderItThread] Mutex Error: WAIT_TIMEOUT" );

  735:          }

   736:             else if( waitError == WAIT_ABANDONED )

   737:             {



SYMBOL_STACK_INDEX:  4

SYMBOL_NAME:  fixfastmdp!decoderItThread+7e

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: FixFastMDP

IMAGE_NAME:  FixFastMDP.exe

DEBUG_FLR_IMAGE_TIMESTAMP:  4d41d25b

FAILURE_BUCKET_ID:  STATUS_BREAKPOINT_80000003_FixFastMDP.exe!decoderItThread

BUCKET_ID:  APPLICATION_FAULT_STATUS_BREAKPOINT_fixfastmdp!decoderItThread+7e

WATSON_STAGEONE_URL:  http://watson.microsoft.com/StageOne/FixFastMDP_exe/0_0_0_0/4d41d25b/unknown/0_0_0_0/bbbbbbb4/80000003/00000000.htm?Retriage=1

我对此所做的所有研究几乎都是空的,即我似乎无法解释 windbg 相对于应用程序本身所说的内容。

FWIW,上面的源代码嵌入在 try/catch 块中,因此应用程序因未捕获的异常而崩溃的事实对我来说表明异常类型非常低。

此外,此应用程序/进程附加了 4 个线程,通常更多。但是 winbdg 只报告了一个与应用程序无关的单个线程。

总结一下

  1. 有人遇到过类似的 WaitForSingleObject 调用问题吗?

  2. 关于为什么 windbg 在应该有更多线程时报告单个线程的任何提示?

提前感谢您提供任何信息/帮助

【问题讨论】:

  • “一个或多个参数无效”似乎表示一个或多个参数无效
  • 你确定 FFDecoderMutex 是句柄吗?也许你需要传递它的地址。
  • 看起来您的互斥对象已被破坏,您正试图锁定它。它是一个完整的内存转储,那么您可能可以检查该变量并检查它是否正确。
  • 感谢上述,Mutext的值为0x0000484。由于我无法通过调用堆栈到达声明 Handle FFDecoderMutex 的范围,因此我不确定如何转储互斥锁的值。我想我需要句柄引用的内存地址,然后查看偏移 x484。但是看到这是一个操作系统控制的区域,我不认为我可以看到 Mutex(?) 的值
  • 它确实看起来像一个伪造的句柄 - 使用 !handle 484 ff 检查它,如果它被证明是无效的,请检查你的代码可能会释放它的位置

标签: c++ windbg


【解决方案1】:

STATUS_BREAKPOINT 表示 CPU 命中了一条int 3 指令;这不会通过操作系统发生,除非您运行已检查的构建(即,当您失败断言时会发生这种情况)。您是否正在运行已检查的构建?

2) 关于为什么 windbg 在应该有更多线程的情况下复制单个线程有任何提示吗?

WinDbg 只是告诉你抛出异常的线程,运行~*k 来显示所有这些。

【讨论】:

  • 嗨,保罗,感谢您的快速回复。源代码中没有明确的 ASSERT stmt,不确定构建中的哪个选项控制它(我使用的是 VS2005 SP1)。我已经验证这是唯一出现的线程(做了一个 ~* 并显示了进程/线程窗口)。
  • 如果您正在运行操作系统的检查版本 (osronline.com/DDKx/ddtools/checked_6dir.htm),当您滥用 API 时,操作系统本身会抛出 int 3。不过,您真的不应该在生产服务器中使用已检查的构建
  • 再次感谢 Paul 的回复。它是一个生产服务器,未经检查的 Windows 2003 Server 版本。
【解决方案2】:

崩溃可能是在不同的线程中。在故障转储上使用.ecxr 以获取实际的崩溃线程。如果~ 只为您提供一个线程,则意味着该进程在附加到服务的故障转储进程之前已经几乎消失了。在这种情况下,您需要将调试器附加到正在运行的应用程序,然后等待崩溃实时发生。

【讨论】:

  • 我已将 windbg 设置为 JIT 调试器,因此当应用程序崩溃时,windbg 会捕获该过程。即使我启动在windbg下运行的应用程序,我似乎也会得到相同的结果,即由于未处理的异常,到windbg获得控制权时应用程序几乎消失了。
  • 通过 JIT 调试,事情可以改变的时间窗口要长得多。如果你将 windbg 附加到正在运行的进程(你可以使用 -g -G 让它保持运行),那么窗口会变得更小。
猜你喜欢
  • 2014-09-29
  • 1970-01-01
  • 1970-01-01
  • 2013-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-11
相关资源
最近更新 更多