2009-01-16 12 views
8

En MFC C++ (Visual Studio 6), estoy acostumbrado a utilizar la macro TRACE para la depuración. ¿Hay una declaración equivalente para plain win32?¿Hay una declaración TRACE para win32 C++ básico?

+0

¿Por qué alguien todavía usa Visual Studio 6 en estos días? El 2005 y ahora 2008 han sido gratis por un largo tiempo. –

Respuesta

7

_RPTn funciona muy bien, aunque no del todo tan conveniente. Here is some code que recrea la instrucción MFC TRACE como una función que permite un número variable de argumentos. También agrega la macro TraceEx que precede el archivo fuente y el número de línea para que pueda hacer clic nuevamente en la ubicación de la declaración.

Actualización: El código original en CodeGuru no compilaría para mí en modo Release, así que cambié la forma en que se eliminan las declaraciones TRACE para el modo Release. Aquí está mi fuente completa que puse en Trace.h. Gracias a Thomas Rizos para el original:

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

Bien, eso es un fragmento útil. –

+0

szBuffer no debería ser global si está utilizando TRACE en más de un hilo – Anders

+0

buen punto - Creo que si solo muevo la declaración dentro de la función TRACE romperá la macro TRACEF, ¿es esto cierto? – jacobsee

3

De la documentación de MSDN, Macros for Reporting:

Puede utilizar el _RPTn y macros _RPTFn, definido en crtdbg.h, para reemplazar el uso de printf para la depuración. Estas macros desaparecen automáticamente en su compilación de lanzamiento cuando _DEBUG no está definido, por lo que no es necesario que las incluya en #ifdefs.

3

También hay OutputDebugString. Sin embargo, eso no se eliminará al compilar la versión.

1

macros traza que proporcionan mensajes con código origen del vínculo, tiempo de ejecución información de pila de llamadas, y función prototipo información con valores de parámetros:

Extended Trace: Trace macros for Win32

1

he encontrado que el uso de la _RPT() macro también funcionará con un archivo fuente C en Visual Studio 2005. Este artículo Debugging with Visual Studio 2005/2008: Logging and Tracing proporciona una descripción general de TRACE, _RPT y otro tipo de registro macros.

genero una línea de un archivo de registro llamado el ASSRTLOG que contiene los registros y al escribir el registro en el archivo, también hago la siguiente línea de código fuente:

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

Esta línea pone el mismo registro que va al archivo de registro en la ventana de salida del IDE de Visual Studio 2005.

Puede que le interese la mecánica detrás del enfoque que estamos utilizando para el registro. Tenemos una función PifLogAbort() que acepta una serie de argumentos que luego se utilizan para generar un registro. Estos argumentos incluyen el nombre del archivo donde se genera el registro junto con el número de línea.La macro se parece a esto:

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

y el prototipo de función para PifLogAbort() tener este aspecto:

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

y utilizar la macro vamos a insertar una línea como esta:

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

Lo que hará esta macro es que si el código de retorno es menor que 0 (la aserción falla), se generará un registro con el texto provisto. El registro incluye la condición que generó el registro junto con el nombre del archivo y el número de línea.

La función PifLogAbort() genera registros con una longitud especificada y trata el archivo de salida como un búfer circular. Los registros también tienen una marca de fecha y hora.

En aquellos casos en los que queremos generar el texto descriptivo de forma dinámica en tiempo de ejecución, tal vez para proporcionar el valor de código de error real, usamos la función sprintf() con un tampón que en la secuencia siguiente código:

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); 
} 

Si no queremos que se generen los registros, todo lo que tenemos que hacer es ir al único archivo de encabezado donde se define la macro y definir que no sea nada y luego volver a compilar. Sin embargo, hemos encontrado que estos registros pueden ser muy valiosos cuando se investigan problemas de campo y son especialmente útiles durante las pruebas de integración.

2

sólo tiene que utilizar algo como esto (de memoria, no se ha probado en absoluto ...)

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

Y entonces puedo escribir cosas como: -

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

que se puede envolver en algunos #ifdefs para eliminarlo en compilaciones de lanzamiento con la suficiente facilidad.

+1

Solo una pequeña corrección: 'OutputDebugString (ss.str(). C_str());' debe usarse en lugar de 'OutputDebugString (msg.str());' – Apokal

0

Windows Events son un reemplazo potencial para las macros TRACE, dependiendo de su situación particular. El código se compila en las configuraciones de depuración y liberación. El seguimiento de eventos se puede habilitar y deshabilitar dinámicamente, mostrar en tiempo real o descargar en la máquina del cliente para un diagnóstico posterior. Las huellas también se pueden correlacionar con la información de seguimiento recopilada de otras partes del sistema operativo.

Si solo necesita volcar información cada vez que el código llega a ciertos puntos de control, junto con contenido variable, seguimientos de pila o nombres de llamadas, Visual Studio Tracepoints es una opción no intrusiva para hacerlo.