2009-01-16 19 views

Antwort

7

_RPTn funktioniert gut, obwohl nicht ganz so bequem. Here is some code, die die MFC-TRACE-Anweisung als eine Funktion neu erstellt, die eine variable Anzahl von Argumenten zulässt. Fügt außerdem ein TraceEx-Makro hinzu, das die Quelldatei und die Zeilennummer voranstellt, sodass Sie auf den Speicherort der Anweisung zurückklicken können.

Update: Der ursprüngliche Code auf CodeGuru würde für mich im Release-Modus nicht kompilieren, also änderte ich die Art, wie TRACE-Anweisungen für den Release-Modus entfernt werden. Hier ist meine vollständige Quelle, die ich in Trace.h eingetragen habe. Dank Thomas Rizos für den ursprünglichen:

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

Schön, das ist ein nützlicher Ausschnitt. –

+0

szBuffer sollte nicht global sein, wenn Sie TRACE in mehr als einem Thread verwenden – Anders

+0

good point - Ich denke, wenn ich die Deklaration einfach in die TRACE-Funktion verschiebe, wird es den TRACEF-Makro allerdings brechen - ist das wahr? – jacobsee

3

aus der MSDN-Dokumentation, Macros for Reporting:

Sie die _RPTn verwenden können, und _RPTFn Makros in Crtdbg.h definiert, die Verwendung von printf-Anweisungen für die Fehlersuche zu ersetzen. Diese Makros verschwinden automatisch in Ihrem Release-Build, wenn _DEBUG nicht definiert ist. Sie müssen daher nicht in #ifdefs eingeschlossen werden.

3

Es wird auch Output. Dies wird jedoch beim Kompilieren der Veröffentlichung nicht entfernt.

1

fand ich, dass die Verwendung von _RPT() Makro wird auch mit einer C-Quelldatei in Visual Studio 2005 arbeiten. Dieser Artikel Debugging with Visual Studio 2005/2008: Logging and Tracing bietet einen Überblick über TRACE, _RPT und andere Protokolltypen Makros.

erzeugen ich eine Linie für eine Protokolldatei der ASSRTLOG genannt, die Protokolle enthält und beim Schreiben des Protokolls in die Datei, kann ich auch die folgende Zeile im Quellcode:

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

Diese Linie stellt das gleiche Protokoll, das wird in die Protokolldatei in das Ausgabefenster von Visual Studio 2005 IDE eingefügt.

Möglicherweise interessieren Sie sich für die Vorgehensweise, die für die Protokollierung verwendet wird. Wir haben eine Funktion PifLogAbort(), die eine Reihe von Argumenten akzeptiert, die dann verwendet werden, um ein Protokoll zu generieren. Zu diesen Argumenten gehört der Name der Datei, in der das Protokoll zusammen mit der Zeilennummer generiert wird.Das Makro sieht wie folgt aus:

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

und die Funktionsprototyp für PifLogAbort() sieht wie folgt aus:

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

und das Makro zu verwenden, werden wir eine Zeile wie diese ein:

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

Was dieser Makro tun wird, ist, dass, wenn der Rückgabecode kleiner als 0 ist (die Assertion fehlschlägt), ein Protokoll mit dem bereitgestellten Text generiert wird. Das Protokoll enthält die Bedingung, die das Protokoll zusammen mit dem Dateinamen und der Zeilennummer generiert hat.

Die Funktion PifLogAbort() generiert Protokolle mit einer bestimmten Länge und behandelt die Ausgabedatei als Ringpuffer. Die Protokolle haben auch einen Zeit- und Datumsstempel.

In jenen Fällen, in denen wir den beschreibenden Text zur Laufzeit dynamisch erzeugt werden sollen, vielleicht den eigentlichen Fehlercodewert zur Verfügung zu stellen, verwenden wir die Funktion sprintf() mit einem Puffer wie im folgenden Codesequenz:

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

Wenn wir wollen, dass die Protokolle nicht generiert werden, müssen wir nur zu der einzelnen Header-Datei gehen, in der das Makro definiert ist, und es als nichts definieren und dann neu kompilieren. Wir haben jedoch festgestellt, dass diese Protokolle bei der Untersuchung von Feldproblemen sehr nützlich sein können und insbesondere bei Integrationstests nützlich sind.

2

ich nur so etwas wie diese verwenden (aus dem Gedächtnis, nicht getestet ...)

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

Und dann kann ich die Dinge schreiben wie: -

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

Sie, dass wickeln können in einige #ifdefs, um es in Release-Builds leicht zu entfernen.

+1

Nur ein kleiner Fehler: 'OutputDebugString (ss.str(). C_str());' sollte anstelle von 'OutputDebugString (msg.str());' verwendet werden – Apokal

0

Windows Events sind ein möglicher Ersatz für TRACE Makros, abhängig von Ihrem speziellen Szenario. Der Code wird in Debug- und Release-Konfigurationen kompiliert. Die Ereignisverfolgung kann dann dynamisch aktiviert und deaktiviert, in Echtzeit angezeigt oder auf dem Computer eines Kunden zur späteren Diagnose ausgegeben werden. Die Traces können auch mit Trace-Informationen korreliert werden, die von anderen Teilen des OS gesammelt werden.

Wenn Sie nur Informationen ausgeben müssen, wenn Code bestimmte Prüfpunkte erreicht, zusammen mit variablen Inhalten, Stack-Traces oder Anrufernamen, ist Visual Studio Tracepoints eine nicht-intrusive Option, dies zu tun.

Verwandte Themen