Есть ли оператор TRACE для базового win32 C ++? - PullRequest
8 голосов
/ 16 января 2009

В MFC C ++ (Visual Studio 6) я привык использовать макрос TRACE для отладки. Есть ли эквивалентное утверждение для простого win32?

Ответы [ 7 ]

8 голосов
/ 16 января 2009

_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
3 голосов
/ 17 января 2009

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

3 голосов
/ 16 января 2009

Из документов MSDN, Макросы для отчетов :

Вы можете использовать макросы _RPTn и _RPTFn, определенные в CRTDBG.H, чтобы заменить использование операторов printf для отладки. Эти макросы автоматически исчезают в вашей сборке выпуска, когда _DEBUG не определен, поэтому нет необходимости заключать их в # ifdefs.

2 голосов
/ 31 октября 2012

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

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

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

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

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

1 голос
/ 31 октября 2012

Я обнаружил, что использование макроса _RPT() также будет работать с исходным файлом C в Visual Studio 2005. Эта статья Отладка с помощью Visual Studio 2005/2008: ведение журнала и трассировка содержит обзор TRACE, _RPT и другие макросы типа ведения журнала.

Я генерирую строку для файла журнала, который называется ASSRTLOG, который содержит журналы, и при записи журнала в файл я также делаю следующую строку исходного кода:

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

Эта строка помещает тот же журнал, который поступает в файл журнала, в окно вывода IDE Visual Studio 2005.

Возможно, вас заинтересует механика, лежащая в основе подхода, который мы используем для регистрации. У нас есть функция 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);
}

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

1 голос
/ 30 января 2009

Макросы трассировки , которые предоставляют сообщения с ссылкой на исходный код , информация о вызове во время выполнения информация и прототип функции информация со значениями параметров :

Расширенная трассировка : Макросы трассировки для Win32

0 голосов
/ 09 декабря 2014

События Windows являются потенциальной заменой макросов TRACE, в зависимости от вашего конкретного сценария. Код компилируется в конфигурации Debug и Release. Затем трассировку событий можно динамически включать и отключать, отображать в режиме реального времени или выгружать на компьютер клиента для последующей диагностики. Трассировки могут быть сопоставлены с информацией трассировки, полученной из других частей ОС.

Если вам просто нужно выгружать информацию всякий раз, когда код достигает определенных контрольных точек, вместе с переменным содержимым, трассировкой стека или именами вызывающих абонентов, Трассировки * Visual Studio * - это ненавязчивая опция для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...