捕获异常时将有用数据转储到控制台
Posted
技术标签:
【中文标题】捕获异常时将有用数据转储到控制台【英文标题】:Dumping Useful Data to Console on Caught Exception 【发布时间】:2010-11-09 22:41:11 【问题描述】:我有一个CExceptionHandler
类,只要我的应用程序检测到运行时异常,就会调用它。例如:
if ( val == NULL )
TRACE(_T("Unexpected NULL in sequence."));
AfxThrowException( ERROR_INVALID_DATA );
AfxThrowException
很简单:
void AfxThrowException( DWORD error )
CExceptionHandler * pException = NULL;
if ( error == 0 )
error = ::GetLastError();
pException = new CExceptionHandler( error );
TRACE(_T("Warning: throwing CSerialException for error %d\n"), error);
THROW(pException);
这是CExceptionHandler
的成员Dump
函数:
void CExceptionHandler::Dump( CDumpContext & dc ) const
CObject::Dump(dc);
dc << "m_dwError = " << m_dwError;
在我的代码中,我有 try
/catch
语句:
try
/* My app does stuff where the exception is thrown. */
catch( CExceptionHandler * ex )
afxDump << _T("Dumping exceptional data: ") << _T("\r\n");
ex->Dump( afxDump );
afxDump << _T("\r\n");
我希望将收集到的调试信息转储到控制台。但是,当 PC 进入 catch
语句(使用断点验证)时,控制台上没有任何反应。我在调试模式下使用 Visual Studio 2008。想法受到赞赏。谢谢。
【问题讨论】:
您是否会抛出动态分配的内存? (泄漏。) @GMan:有没有你使用“原因”而不是“结果”的结果?:)
(哦,我认为这对你来说是 MFC。但我对此事的看法只是传闻......)
控制台?这不是MFC吗?试试输出窗口。
@Hans Passant:CExceptionHandler
是 MFC (.dll),但应用程序 (.exe) 不是(Win32 控制台项目)。
嗨,吉姆,我已经根据您的评论更新了我的答案。
【参考方案1】:
CDumpContext
将输出发送到调试器,而不是控制台(有关详细信息,请参阅OutputDebugString
),如果您在 Visual Studio 调试器下运行,输出将出现在 Output窗口。
如果您还想将输出发送到控制台,您可以通过在CDumpContext
constructor 中传递指向CFile
对象的指针,将CDumpContext
配置为写入CFile
。
如果您的应用程序是使用“使用多字节字符集”配置选项构建的,您可以使用 CStdioFile
写入 stdout 或 stderr:
CStdioFile file(stdout);
CDumpContext dumpContext(&file);
ex->Dump(dumpContext);
或者,如果你想使用afxDump
,你可以直接设置它的m_pFile
成员变量(它被声明为public
)。例如,您可以将此代码放入您的 main
函数中:
CStdioFile file(stdout);
afxDump.m_pFile = &file;
但是,如果您的应用程序构建为 Unicode,这将不起作用,因为字符串需要转换为多字节才能写入标准输出。要进行转换,请编写一个继承 CFile
的类:
class CDumpFile : public CFile
public:
virtual void Write(const void* lpBuf, UINT nCount);
;
void CDumpFile::Write(const void* lpBuf, UINT nCount)
// Construct string from array of wide chars
const wchar_t* p = static_cast<const wchar_t*>(lpBuf);
UINT len = nCount / sizeof(wchar_t);
CStringW str(p, len);
CStringA astr(str); // Convert wide char to multibyte
fputs((LPCSTR)astr, stdout); // Write multibyte string to stdout
并像这样使用它:
CDumpFile file;
afxDump.m_pFile = &file;
关于您的代码的其他几点:
您应该确保在catch
块中删除异常对象。如果您的CExceptionHandler
类继承了MFC 的CException
,那么您应该调用ex->Delete()
。如果没有,您需要delete ex
。
我建议不要将 Afx
前缀用于自己的函数 - 在我看来,您应该考虑将其保留给 MFC 库使用。
我希望这会有所帮助!
【讨论】:
谢谢!我使用CDumpContext dumpContext(&file)
实现了该解决方案,并且它在大多数情况下都有效。但是,它会隔开字符(a C E x c e p t i o n H a n d l e r a t $ 0 0 E 2 4 E 4 0 m _ d w E r r o r = 1 7 0
。对导致此问题的原因有什么想法吗?
是的,这是因为 CStdioFile
正在将 wchar_t
字符串写入控制台,这需要 MBCS。请参阅我的更新答案。以上是关于捕获异常时将有用数据转储到控制台的主要内容,如果未能解决你的问题,请参考以下文章