0

我正在使用一个 C++ 项目(我不是该项目的作者),它有很多 MFC 字符串格式化函数。不幸的是,像%dand之类的东西%s非常接近(包括键盘上字母 d 和 s 的位置),一个可以与另一个互换。所以我有时可能会看到这样的代码行:

CString s;
s.Format(L"Value v=%s", 100);    //Should've been %d instead

这会导致流程严重崩溃,在最终项目中很难定位和隔离。所以我正在考虑将Format函数包装在我自己的覆盖中并捕获异常并在它作为未处理的异常抛出之前记录它。

所以我采用了以下构造:

__try
{
    //Do the Format function here
}
__except(1)
{
    //Log the error, etc.
}

但不幸的是,上面的构造没有从第一个代码块中捕获异常,所以我启动了 VS 2008 C++ 调试器并显示了这一点:

在此处输入图像描述

然后我尝试了这个:

try
{
    //Do the Format function here
}
catch(int e)
{
    //Do the logging
}

但这也没有抓住它。

那么我怎么能抓住这个错误呢?

PS。我还有第二个问题。是否有一种简单的方法可以覆盖 MFC 函数,例如Format

4

3 回答 3

0

您可以使用_set_se_translator()将 SEH 异常(如访问冲突)转换为 C++ 异常,然后您可以使用except().

一些示例代码: http: //www.codeproject.com/Articles/422/SEH-and-C-Exceptions-catch-all-in-one

于 2013-09-13T10:03:32.087 回答
0

正如其他人已经说过的那样,低级异常(如访问冲突)与 C++ 异常不同。它们属于结构化异常处理术语,并且需要其他方法来捕获,至少在默认情况下是这样。

可以更改编译器设置(至少在 Visual Studio 中)以使其将这些异常包装到 C++ try/catch 语句可以处理的内容中,但我记得这会丢失有关 SEH 异常是什么以及它来自何处的详细信息。

通过一种或另一种方式,您可能会获得足够好的异常来帮助追踪这些问题,但还有另一种方式:使用静态代码分析。

虽然标准 C++ 编译器通常不会验证 format/printf 样式的调用,但有多种工具可以验证。事实上,Visual Studio 的一些最新版本/版本附带了一个代码分析工具,尽管它可能在您提到的 VS 2008 中不可用。因此,您可能值得做一些研究,看看您是否可以获得某种代码分析工具,然后可以在分析/编译时而不是运行时捕获所有 CString::Format 错误。

于 2013-09-13T04:17:46.447 回答
0

MFC 抛出CException指针,所以你可以试试这个:

try
{
    // Do the Format function here
}
catch(CException* e)
{
    // Do the logging then free the exception
    if (m_bThrowExceptionAgain)
        throw; // Do not delete e 
    else 
        e->Delete();
}

如示例所示,一旦捕获异常对象,就必须删除它。还要确保在编译器中启用了 C++ 异常。有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/0e5twxsh.aspx

于 2013-09-13T02:06:57.337 回答