什么是 ntdll.dll!RcConsolidateFrames?

sou*_*pim 6 c++ dump crash-dumps visual-c++

我的转储文件中有一个如下所示的调用堆栈。我想在调用堆栈中找到我的代码,但找不到。分析我的转储的起点是什么?我的程序的链接选项是release/Od。

msvcr120.dll!abort() 
msvcr120.dll!terminate()
msvcp120.dll!_Call_func$catch()
msvcr120.dll!_CallSettingFrame()
msvcr120.dll!__CxxCallCatchBlock(_EXCEPTION_RECORD * pExcept=0x0000002885f9b010)
ntdll.dll!RcConsolidateFrames()
msvcp120.dll!_Call_func(void * _Data=0x00000028835d5ce0)
msvcr120.dll!_callthreadstartex()
msvcr120.dll!_threadstartex(void * ptd=0x000000288366e410)
kernel32.dll!BaseThreadInitThunk()
ntdll.dll!RtlUserThreadStart()
Run Code Online (Sandbox Code Playgroud)

Mar*_* Ba 2

TL;DR:如果您重新throw;调用堆栈,则不会显示原始位置,而是显示堆栈上方的内容ntdll.dll!RcConsolidateFrames()


当代码在 x64 二进制文件中使用时,您将ntdll.dll!RcConsolidateFrames()在调用堆栈中找到未处理的异常,而不是实际位置。catch(ANYTHING) + throw;

你看,如果你catch重新抛出,原来的调用堆栈已经被展开了,当你然后throw;它会重新抛出原来的异常,但是调用堆栈信息现在被搞乱了。

我对 MSVC 的观察是,任何throw;未处理并导致转储文件的内容总是会发生这种情况。具体来说:

  • 无论使用catch(...)还是catch(cppTypeEx&)
  • 它是 C++ 异常(带有或)还是 SEH 异常(带有)并不重要/EHsc/EHa/EHa
  • 它在调试器和转储文件中看起来像这样。

底线:throw;会弄乱你的调用堆栈