2008-08-26 5 views
10

TRACE macro может использоваться для вывода диагностических сообщений в отладчик при компиляции кода в Отладка. Мне нужны те же сообщения, что и в режиме Release. Есть ли способ достичь этого?Как включить макрос TRACE в режиме Release?

(Пожалуйста не тратить время обсуждения, почему я не должен использовать TRACE в режиме Release :-)

+0

Для АТЛ В проектах у меня есть класс drop-in, который переопределяет макросы ATLTRACE и карты в Outp utDebugString` (включая принятие гибкого числа параметров): http://alax.info/blog/tag/outputdebugstring – 2012-11-26 21:53:07

ответ

8

На самом деле макрос TRACE намного более гибкий, чем OutputDebugString. Требуется строка стиля и список параметров формата printf(), тогда как OutputDebugString принимает только одну строку. Для реализации полной функциональности TRACE в режиме выпуска, что нужно сделать что-то вроде этого:

void trace(const char* format, ...) 
{ 
    char buffer[1000]; 

    va_list argptr; 
    va_start(argptr, format); 
    wvsprintf(buffer, format, argptr); 
    va_end(argptr); 

    OutputDebugString(buffer); 
} 
+4

Я знаю, что это всего лишь пример, но в этом примере есть огромный потенциал переполнения буфера, который принимает как есть. – Aardvark 2008-09-16 19:04:17

1

В MFC TRACE определяется как ATLTRACE. И в режиме выпуска, который определяется как:

#define ATLTRACE   __noop 

Таким образом, используя прослеживать коробки из MFC, вы на самом деле не быть в состоянии прочитать любой текст TRACE, потому что он даже не будет написано вне. Вместо этого вы можете написать свою собственную функцию TRACE, а затем переопределить макрос TRACE. Вы можете сделать что-то вроде этого:

void MyTrace(const CString& text) 
{ 
    ::OutputDebugString(text); // Outputs to console, same as regular TRACE 
    // TODO: Do whatever output you need here. Write to event log/write to text file/write to pipe etc. 
} 
2

TRACE - это просто макрос для OutputDebugString. Таким образом, вы можете просто просто создать свой собственный макрос TRACE (или назвать его чем-то другим), который вызывается OutputDebugString.

4

Несколько лет назад мне нужно схожая функциональность, так что я починил следующий код. Просто сохраните его в файле, например. rtrace.h, включите его в конец вашего stdafx.h и добавьте _RTRACE в режим освобождения, заданный препроцессором.

Может быть кто-то найдет применение для него :-)

Джон

 
#pragma once 

//------------------------------------------------------------------------------------------------ 
// 
// Author: John Cullen 
// Date:  2006/04/12 
// Based On: MSDN examples for variable argument lists and ATL implementation of TRACE. 
// 
// Description: Allows the use of TRACE statements in RELEASE builds, by overriding the 
// TRACE macro definition and redefining in terms of the RTRACE class and overloaded 
// operator(). Trace output is generated by calling OutputDebugString() directly. 
// 
// 
// Usage: Add to the end of stdafx.h and add _RTRACE to the preprocessor defines (typically 
//   for RELEASE builds, although the flag will be ignored for DEBUG builds. 
// 
//------------------------------------------------------------------------------------------------ 

#ifdef _DEBUG 

// NL defined as a shortcut for writing FTRACE(_T("\n")); for example, instead write FTRACE(NL); 
#define NL _T("\n") 
#define LTRACE TRACE(_T("%s(%d): "), __FILE__, __LINE__); TRACE 
#define FTRACE TRACE(_T("%s(%d): %s: "), __FILE__, __LINE__, __FUNCTION__); TRACE 

#else // _DEBUG 

#ifdef _RTRACE 
#undef TRACE 
#define TRACE RTRACE() 
#define LTRACE RTRACE(__FILE__, __LINE__) 
#define FTRACE RTRACE(__FILE__, __LINE__, __FUNCTION__) 
#define NL _T("\n") 

class RTRACE 
{ 
public: 
    // default constructor, no params 
    RTRACE(void) : m_pszFileName(NULL), m_nLineNo(0), m_pszFuncName(NULL) {}; 

    // overloaded constructor, filename and lineno 
    RTRACE(PCTSTR const pszFileName, int nLineNo) : 
     m_pszFileName(pszFileName), m_nLineNo(nLineNo), m_pszFuncName(NULL) {}; 

    // overloaded constructor, filename, lineno, and function name 
    RTRACE(PCTSTR const pszFileName, int nLineNo, PCTSTR const pszFuncName) : 
     m_pszFileName(pszFileName), m_nLineNo(nLineNo), m_pszFuncName(pszFuncName) {}; 

    virtual ~RTRACE(void) {}; 

    // no arguments passed, e.g. RTRACE()() 
    void operator()() const 
    { 
     // no arguments passed, just dump the file, line and function if requested 
     OutputFileAndLine(); 
     OutputFunction(); 
    } 

    // format string and parameters passed, e.g. RTRACE()(_T("%s\n"), someStringVar) 
    void operator()(const PTCHAR pszFmt, ...) const 
    { 
     // dump the file, line and function if requested, followed by the TRACE arguments 
     OutputFileAndLine(); 
     OutputFunction(); 

     // perform the standard TRACE output processing 
     va_list ptr; va_start(ptr, pszFmt); 
     INT len = _vsctprintf(pszFmt, ptr) + 1; 
     TCHAR* buffer = (PTCHAR) malloc(len * sizeof(TCHAR)); 
     _vstprintf(buffer, pszFmt, ptr); 
     OutputDebugString(buffer); 
     free(buffer); 
    } 

private: 
    // output the current file and line 
    inline void OutputFileAndLine() const 
    { 
     if (m_pszFileName && _tcslen(m_pszFileName) > 0) 
     { 
      INT len = _sctprintf(_T("%s(%d): "), m_pszFileName, m_nLineNo) + 1; 
      PTCHAR buffer = (PTCHAR) malloc(len * sizeof(TCHAR)); 
      _stprintf(buffer, _T("%s(%d): "), m_pszFileName, m_nLineNo); 
      OutputDebugString(buffer); 
      free(buffer); 
     } 
    } 

    // output the current function name 
    inline void OutputFunction() const 
    { 
     if (m_pszFuncName && _tcslen(m_pszFuncName) > 0) 
     { 
      INT len = _sctprintf(_T("%s: "), m_pszFuncName) + 1; 
      PTCHAR buffer = (PTCHAR) malloc(len * sizeof(TCHAR)); 
      _stprintf(buffer, _T("%s: "), m_pszFuncName); 
      OutputDebugString(buffer); 
      free(buffer); 
     } 
    } 

private: 
    PCTSTR const m_pszFuncName; 
    PCTSTR const m_pszFileName; 
    const int m_nLineNo; 
}; 

#endif // _RTRACE 

#endif // NDEBUG 

2

Это самый просто код, который я имел видеть

#undef ATLTRACE 
#undef ATLTRACE2 

#define ATLTRACE2 CAtlTrace(__FILE__, __LINE__, __FUNCTION__) 
#define ATLTRACE ATLTRACE2 

см http://alax.info/blog/1351