Существует ли инструкция TRACE для базового win32 C ++?

StackOverflow https://stackoverflow.com/questions/451749

  •  19-08-2019
  •  | 
  •  

Вопрос

В MFC C ++ (Visual Studio 6) Я привык использовать макрос трассировки для отладки.Существует ли эквивалентный оператор для обычного win32?

Это было полезно?

Решение

_RPTn прекрасно работает, хотя и не так удобно. Вот код , воссоздающий инструкцию MFC TRACE как функцию разрешая переменное количество аргументов. Кроме того, добавляется макрос TraceEx, который добавляется к исходному файлу и номеру строки, чтобы вы могли вернуться к местоположению оператора.

Обновление: оригинальный код в CodeGuru не будет компилироваться для меня в режиме выпуска, поэтому я изменил способ удаления операторов TRACE для режима выпуска. Вот мой полный источник, который я поместил в Trace.h. Спасибо Томасу Ризосу за оригинал :

// 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

Другие советы

Существует также OutputDebugString. Однако это не будет удалено при компиляции релиза.

Я просто использую что-то вроде этого (из памяти, вообще не тестировалось ...)

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

И тогда я могу написать что-то вроде: -

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

Вы можете обернуть это в некоторые #ifdefs, чтобы удалить их в сборках релиза достаточно легко.

Я обнаружил, что с помощью _RPT() макрос также будет работать с исходным файлом C в Visual Studio 2005.Эта статья Отладка с помощью Visual Studio 2005/2008:Ведение журнала и отслеживание содержит обзор макросов трассировки, _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);
}

Если мы хотим, чтобы журналы не генерировались, все, что нам нужно сделать, это перейти к единственному заголовочному файлу, где определен макрос, и определить, что это ничего не значит, а затем перекомпилировать.Однако мы обнаружили, что эти журналы могут быть очень ценными при исследовании проблем на местах и особенно полезны во время интеграционного тестирования.

Windows Events are a potential replacement for TRACE macros, depending on your particular scenario. The code gets compiled into both Debug and Release configurations. Event tracing can then be dynamically enabled and disabled, displayed in real-time, or dumped on a client's machine for later diagnosis. The traces can be correlated with trace information gathered from other parts of the OS as well.

If you merely need to dump information whenever code reaches certain checkpoints, together with variable content, stack traces, or caller names, Visual Studio's Tracepoints are a non-intrusive option to do so.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top