是否有基本win32 C ++的TRACE语句?

时间:2009-01-16 20:00:16

标签: c++ debugging winapi vc6

在MFC C ++(Visual Studio 6)中,我习惯使用TRACE宏进行调试。普通win32是否有相同的声明?

7 个答案:

答案 0 :(得分:8)

_RPTn效果很好,但不太方便。 Here is some code将MFC TRACE语句重新创建为允许可变数量参数的函数。还添加了跟踪源文件和行号的TraceEx宏,以便您可以单击返回语句的位置。

更新:CodeGuru上的原始代码不会在发布模式下为我编译,因此我更改了为发布模式删除TRACE语句的方式。以下是我在Trace.h中的完整资源。 感谢Thomas Rizos的原作

// TRACE macro for win32
#ifndef __TRACE_H__850CE873
#define __TRACE_H__850CE873

#include <crtdbg.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>

#ifdef _DEBUG
#define TRACEMAXSTRING  1024

char szBuffer[TRACEMAXSTRING];
inline void TRACE(const char* format,...)
{
    va_list args;
    va_start(args,format);
    int nBuf;
    nBuf = _vsnprintf(szBuffer,
                   TRACEMAXSTRING,
                   format,
                   args);
    va_end(args);

    _RPT0(_CRT_WARN,szBuffer);
}
#define TRACEF _snprintf(szBuffer,TRACEMAXSTRING,"%s(%d): ", \
                &strrchr(__FILE__,'\\')[1],__LINE__); \
                _RPT0(_CRT_WARN,szBuffer); \
                TRACE
#else
// Remove for release mode
#define TRACE  ((void)0)
#define TRACEF ((void)0)
#endif

#endif // __TRACE_H__850CE873

答案 1 :(得分:3)

来自msdn docs,Macros for Reporting

  

您可以使用CRTDBG.H中定义的_RPTn和_RPTFn宏来替换使用printf语句进行调试。当未定义_DEBUG时,这些宏会在发布版本中自动消失,因此不需要将它们包含在#ifdefs中。

答案 2 :(得分:3)

还有OutputDebugString。但是,在编译版本时不会删除它。

答案 3 :(得分:2)

我只是使用这样的东西(来自内存,根本没有测试......)

#define TRACE(msg) {\
    std::ostringstream ss; \
    ss << msg << "\n"; \
    OutputDebugString(msg.str()); \
}

然后我可以写下这样的话: -

TRACE("MyClass::MyFunction returned " << value << " with data=" << some.data);

您可以将其包装在某些#ifdefs中,以便在发布版本中轻松删除它。

答案 4 :(得分:1)

跟踪宏,提供包含源代码链接运行时callstack 信息和函数原型的消息带参数值的信息:

Extended Trace: Trace macros for Win32

答案 5 :(得分:1)

我发现使用_RPT()宏也可以在Visual Studio 2005中使用C源文件。本文Debugging with Visual Studio 2005/2008: Logging and Tracing概述了TRACE,_RPT和其他日志记录类型的宏。

我为名为ASSRTLOG的日志文件生成一行,其中包含日志,在将日志写入文件时,我还执行以下源代码行:

_RPT1(_CRT_WARN, "ASSRTLOG: %s", szLog1);

此行将进入日志文件的相同日志放入Visual Studio 2005 IDE的输出窗口。

您可能对我们用于记录的方法背后的机制感兴趣。我们有一个函数PifLogAbort(),它接受​​一系列参数,然后用于生成日志。这些参数包括生成日志的文件的名称以及行号。宏看起来像这样:

#define NHPOS_ASSERT_TEXT(x, txt) if (!(x)) { PifLogAbort( (UCHAR *)  #x , (UCHAR *)  __FILE__ , (UCHAR *) txt , __LINE__ );}

并且PifLogAbort()的函数原型如下所示:

PifLogNoAbort(UCHAR *lpCondition, UCHAR *lpFilename, UCHAR *lpFunctionname, ULONG ulLineNo)

并使用宏我们将插入一行如下:

NHPOS_ASSERT_TEXT(sBRetCode >= 0, "CliEtkTimeIn():  EtkTimeIn() returned error");

这个宏将做的是,如果返回代码小于0(断言失败),将使用提供的文本生成日志。该日志包括生成日志以及文件名和行号的条件。

函数PifLogAbort()生成具有指定长度的日志,并将输出文件视为循环缓冲区。日志也有时间和日期标记。

在我们想要在运行时动态生成描述性文本的情况下,也许是为了提供实际的错误代码值,我们使用带有缓冲区的sprintf()函数,如下面的代码序列:

if (sErrorSave != STUB_BM_DOWN) {
    char xBuff[128];
    sprintf(xBuff, "CstSendBMasterFH: CstComReadStatus() - 0x%x, sError = %d", usCstComReadStatus, CliMsg.sError);
    NHPOS_ASSERT_TEXT((sErrorSave == STUB_BM_DOWN), xBuff);
}

如果我们不希望生成日志,我们需要做的就是转到定义宏的单个头文件,并将其定义为无需重新编译。但是,我们发现这些日志在调查现场问题时非常有价值,在集成测试期间尤其有用。

答案 6 :(得分:0)

Windows EventsTRACE宏的潜在替代品,具体取决于您的具体情况。代码被编译为Debug和Release配置。然后,可以动态启用和禁用事件跟踪,实时显示或转储到客户端的计算机上以供以后诊断。跟踪可以与从OS的其他部分收集的跟踪信息相关联。

如果您只需要在代码到达某些检查点时转储信息,以及可变内容,堆栈跟踪或调用者名称,Visual Studio的Tracepoints是一个非侵入性选项。