MFC断言可在全局析构函数中工作

时间:2019-05-21 20:48:35

标签: c++ winapi visual-studio-2017 mfc assert

我正在用Visual Studio 2017编写MFC GUI应用程序。我自然是在使用其ASSERT/VERIFY宏来进行一些调试器代码检查。但不幸的是,这些功能无法在全球破坏者中发挥作用。例如,如果我有这样的东西:

struct MY_STRUCT{
    HANDLE hHandle;

    MY_STRUCT()
        : hHandle(NULL)
    {
    }

    ~MY_STRUCT()
    {
        //Make sure handle was released
        ASSERT(hHandle == NULL);
    }
};

//On the global scale
MY_STRUCT mys;

如果触发了MY_STRUCT的析构函数中的断言,它将仅发出警告蜂鸣声,但不会显示断言对话框,并且过程将终止。因此,很难看出是哪个ASSERT产生了它。

(发生这种情况是因为ASSERT内部使用的MessageBox函数在进程终止时无法显示对话框窗口。)

要解决这个问题,我在自己定义的宏版本中使用了FatalAppExit API:

#ifdef _DEBUG
#define ASSERT2(f) {if(!(f))\
{\
        char __buffer123456789[256*4];\
        wsprintfA(__buffer123456789, "ASSERTION!!!\nFile: %s\nLine: %d\nGetLastError() = %d", __FILE__, __LINE__, ::GetLastError());\
        FatalAppExitA(0, __buffer123456789);\
}}
#else
#define ASSERT2(f) ((void)0)
#endif

即使我的ASSERT2在停止退出过程的同时似乎显示了一个断言对话框:

enter image description here

如果我在VS 2017调试器下运行进程,它不会让我中断。

有没有人可以解决我的问题?

  • 中断我的GUI进程。
  • 显示一个断言对话框。
  • 如果正在运行我的JIT调试器,则可以选择调用它。

PS。我在这里不询问有关文本文件错误的记录。

1 个答案:

答案 0 :(得分:1)

发布此问题后不久,我找到了解决方案。在这里:

#ifdef _DEBUG
#define ASSERT2(f) {if(!(f))\
{\
        if(::IsDebuggerPresent()) { ::DebugBreak(); } \
        char __buffer123456789[256*4];\
        wsprintfA(__buffer123456789, "ASSERTION!!!\nFile: %s\nLine: %d\nGetLastError() = %d", __FILE__, __LINE__, ::GetLastError());\
        FatalAppExitA(0, __buffer123456789);\
}}
#else
#define ASSERT2(f) ((void)0)
#endif

#ifdef _DEBUG
#define VERIFY2(f) ASSERT2(f)
#else
#define VERIFY2(f) ((void)(f))
#endif

如果有人有更好的主意,我会保留这个问题。