什么会导致调用堆栈中的ntdll.dll!RcConsolidateFrame?

时间:2016-12-01 22:45:13

标签: c++ visual-studio-2013 exception-handling

我的问题是,什么可能导致调用RcConsolidateFrames?这会混淆调用堆栈吗?

我正在努力获得用于在C ++中进行调试的良好调用堆栈(我可以在那里进行更多细节,但希望将其专注于一个可回答的问题)。我们正在使用带有/ EHa的Visual Studio 2013(v120)编译器(异步 - 基本上也获得SEH)异常处理。由于使用/ EHa,在try-catch(...)块中,我们将所有异常视为致命异常,并且在catch(...)块的末尾,我们使用throw;重新抛出异常

我一直在尝试在C ++的异常处理工具箱(UnhandledExceptionFilter,Try-Catch,Abort Handlers等)中找到各种工具的正确组合,以便在尽可能多的情况下让我们获得可靠的调用堆栈。现在,我可以获得一个很好的调用堆栈(通过'好'我的意思是它指向抛出异常的行),生产代码中只有一个UnhandledExceptionFilter。当我开始添加任何try-catch行为时,它开始变得混乱。

长话短说,我可以在测试程序中添加一些try-catch块,这些块的行为与我期望的一样。在我们的生产代码中,它的行为有所不同,我不知道为什么。我一直在寻找线索,我发现的一条线索是调用堆栈中的这一行:ntdll.dll!RcConsolidateFrames() Unknown。在我们其中一个类的ctor周围添加try-catch块后,我看到了这一行。此时,调用堆栈接近(ish)但不包括throw。以下是生产代码中的示例调用堆栈,其中一些名称已更改:

>   KernelBase.dll!RaiseException()    Unknown
    msvcr120d.dll!__RethrowException(EHExceptionRecord * pThisException) Line 1234  C++
    msvcr120d.dll!__CxxCallCatchBlock(_EXCEPTION_RECORD * pExcept) Line 1296    C++
    ntdll.dll!RcConsolidateFrames()    Unknown  
    OneOfOurDlls.dll!OurNamespace::someFunction() Line 72   C++  
    OurMainProgram.exe!wmain(int argc, wchar_t * * argv) Line 39    C++
    [External Code] 

这是一个简单的示例程序,我可以在我的桌面上运行,它为我提供了我期望的行为,并且在生产中没有看到类似的情况(没有RcConsolidateFrames)。

Main.cpp

#include "A.h"
#include <Windows.h>
#include <iostream>
#include <memory>

LONG WINAPI UnhandledExceptionFilter(_In_ struct _EXCEPTION_POINTERS *ExceptionInfo)
{
    std::cout << "!!!*** UnhandledExceptionFilter ***!!!" << std::endl;

    return EXCEPTION_CONTINUE_SEARCH;
}

void main()
{
    std::cout << "main()" << std::endl;

    SetUnhandledExceptionFilter(UnhandledExceptionFilter);

    try
    {
        auto a = std::make_unique<A>();
        a->createB(true);
    }
    catch (...)
    {
        std::cout << "main() -- catch(...)" << std::endl;
        throw;
    }
}

A.h A.cpp

#pragma once

class A
{
public:
    A();
    ~A();

    void createB(bool bThrowsInCtor);
};

#include "A.h"
#include "B.h"
#include <iostream>
#include <memory>

A::A()
{
    std::cout << " A::A()" << std::endl;
}

A::~A()
{
    std::cout << " A::~A()" << std::endl;
}

void A::createB(bool bThrowsInCtor)
{
    try
    {
        std::cout << " A::createB -- throws = " << bThrowsInCtor << std::endl;
        auto b = std::make_unique<B>(bThrowsInCtor);
    }
    catch (...)
    {
        std::cout << " A::createB -- catch(...)" << std::endl;
        throw;
    }
}

B.h B.cpp

#pragma once

class B
{
public:
    B(bool throws);
    ~B();
};

#include "B.h"
#include <iostream>

B::B(bool throws)
{
    std::cout << "  B::B()" << std::endl;
    if (throws)
    {
        std::cout << "  throwing std::runtime_error" << std::endl;
        throw std::runtime_error("B::B()");
    }
}

B::~B()
{
    std::cout << "  B::~B()" << std::endl;
}

输出

main()
 A::A()
 A::createB -- throws = 1
  B::B()
  throwing std::runtime_error
 A::createB -- catch(...)
 A::~A()
main() -- catch(...)
!!!*** UnhandledExceptionFilter ***!!!

Good Call Stack

    KernelBase.dll!_RaiseException@16()    Unknown
    [External Code] 
>   BlankVS2013Project.exe!B::B(bool throws) Line 12    C++
    [External Code] 
    BlankVS2013Project.exe!A::createB(bool bThrowsInCtor) Line 21   C++
    BlankVS2013Project.exe!main() Line 23   C++
    [External Code] 

0 个答案:

没有答案