我正在处理一个C++项目(我不是该项目的作者),该项目有很多MFC字符串格式化函数。不幸的是,像%d
和%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.
}
但不幸的是,上面的构造没有捕捉到第一个代码块中的异常,所以我让VS2008 C++调试器启动并显示了以下内容:
然后我尝试了一下:
try
{
//Do the Format function here
}
catch(int e)
{
//Do the logging
}
但这也没有抓住它。
那么,我如何才能捕捉到这个错误呢?
PS。我还有第二个问题。有没有简单的方法来覆盖一个MFC函数,比如Format?
发布于 2013-09-13 10:06:57
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-13 12:17:46
正如其他人已经说过的,低级异常(如访问冲突)与C++异常不同。它们属于术语Structured Exception Handling,需要其他方法才能捕获,至少默认情况下是这样。
可以更改编译器设置(至少在Visual Studio中),使其将这些异常包装到C++ try/catch语句可以处理的内容中,但我记得这会丢失有关statements是什么以及它来自何处的详细信息。
无论以何种方式,您可能会让异常工作得足够好,以帮助跟踪这些问题,但也有另一种方法:使用静态代码分析。
虽然标准的C++编译器通常不会验证格式/打印样式的调用,但有各种工具可以验证。事实上,Visual Studio的一些最新版本附带了一个code analysis tool,尽管在您提到的VS2008中可能没有提供它。因此,你可能有必要做一些研究,看看是否可以获得某种代码分析工具,这样就可以在分析/编译时而不是运行时捕获所有CString::格式错误。
发布于 2013-09-13 18:03:32
您可以使用_set_se_translator()
将访问冲突等SEH异常转换为C++异常,然后使用except()
捕获这些异常。
一些示例代码:http://www.codeproject.com/Articles/422/SEH-and-C-Exceptions-catch-all-in-one
https://stackoverflow.com/questions/18776881
复制相似问题