Windows-spårförberedare - Windows software trace preprocessor

Den Windows programvara spår preprocessor ( WPP , förbehandlaren och tillhörande stödverktyg kallas WPP Software Tracing ) är en preprocessor som förenklar användningen av WMI händelse spåra att genomföra en effektiv programvara spårning i drivrutiner och program som riktar Windows 2000 och senare operativsystem. WPP skapades av Microsoft och ingår i Windows DDK . Även om WPP är brett i dess tillämpbarhet, ingår den inte i Windows SDK , och används därför främst för drivrutiner och drivrutinssupport som produceras av mjukvaruförsäljare som köper Windows DDK.

Bakgrund

Spårning av programvara är en specialiserad användning av loggning för att registrera information om programmets körning. Denna information används ofta för felsökning . Till skillnad från händelseloggning , vars huvudsakliga syfte är att producera register över händelser som kan granskas av systemadministratörer (se till exempel Event Viewer ) eller analyseras med hanteringsverktyg, är spårning av programvara främst ett felsökningshjälpmedel för programutvecklare . Som sådant är många av de icke-funktionella kraven för händelseloggning, såsom lokaliserbarhet eller ett standardbaserat utgångsformat, uttryckligen icke-mål för de flesta applikationer av programvaraspårning. Å andra sidan har spårning av programvara speciella krav på prestanda som i allmänhet inte är lika viktiga vid händelseloggning. Till exempel producerar en vanlig användning av programvaraspårning, in / out-spårning output vid ingångspunkten och returnering av funktioner eller metoder så att en utvecklare visuellt kan följa exekveringsvägen, ofta inklusive parametrar och returvärden , i en felsökare eller text -baserad loggfil (detta kan ses som en run-time- analog till ett sekvensdiagram ). Denna typ av spårning, även om den är användbar för utvecklare, kan skada prestandan för en mjukvaruprodukt kraftigt om den inte kan inaktiveras (antingen vid kompileringstid via villkorlig sammanställning eller vid körning via flaggor ).

Ytterligare överväganden som är speciella för spårning av programvara inkluderar följande:

  • I egenutvecklad programvara kan spårningsdata innehålla känslig information om produktens källkod .
  • Om spårning är aktiverad eller inaktiverad vid körning kräver många spårningsmetoder en betydande mängd ytterligare data i binären, vilket indirekt kan skada prestanda även när spårning är inaktiverad.
  • Om spårning är aktiverad eller inaktiverad vid sammanställningstiden, beror på att spårningsdata för ett problem på en kundmaskin beror på att kunden är villig och kan installera en speciell, spårningsaktiverad version av din programvara.
  • Vissa typer av programvara, t.ex. drivrutiner, måste uppfylla strikta prestandakrav även om spårning är aktiverad.

På grund av de två första övervägandena använder traditionella metoder för spårning av programvara villkorlig sammanställning för att aktivera eller inaktivera spårning (och inkludering av spårningsdata) vid sammanställningstiden. Användning av C-förbehandlaren kan till exempel definiera ett makro DebugOutenligt följande:

#ifdef _DEBUG
#define DebugOut(msg, ...) \
    DebugPrintf(__FUNCTION__ "(" __FILE__ ":" TO_STRING(__LINE__) ")\t" \
        msg, __VAR_ARGS__)
#else
#define DebugOut(msg, ...)
#endif

där TO_STRINGär ett makro som konverterar radnumret ( __LINE__) till en sträng och DebugPrintfär en printf- liknande funktion som till exempel kan mata ut text till felsökaren.

Sedan följande kod:

DebugOut("Error %d occurred\n", error_code);

skulle producera output som liknar följande på felsökningsbyggnader:

SomeFunction(file.c:78)    Error 217 occurred

En annan teknik för vissa typer av spårning (särskilt in / out-spårning) är att använda instrumentering . Även om den här tekniken kan hantera många av de största problemen, är den inte alltid tillgänglig (vanligtvis endast i hanterad kod ).

WMI-händelsespårning är ett exempel på en teknik som särskilt behandlar prestandan för spårning i prestandakritisk kod som förare. Det kan också hantera oroet för att kontrollera distributionen av känslig spårinformation genom att låta en utvecklare definiera de mänskliga läsbara spårningsdata ( "Error %d occurred\n"i exemplet ovan) separat från koden så att den inte är inbyggd i produkten (i koden, en specifikt meddelande hänvisas till med dess meddelandenummer). Det finns dock några viktiga begränsningar:

  • WMI-händelsespårning kan inte i sig själv generera "SomeFunction(file.c:78)"delen av spårmeddelandet automatiskt . Detta är en begränsning av all sådan teknik, inte specifik för WMI-händelsespårning.
  • Att kräva den mänskliga läsbara delen av spårningsdata som ska separeras från koden kan minska koden läsbarhet.
  • Att använda denna teknik kan införa betydande utvecklingsomkostnader för "one-shot" spårningsmeddelanden.

Drift av WPP

WPP körs före kompilering (med andra ord, till och med C-förbehandlaren), och genererar ett spårmeddelandeshuvud för varje fil som den behandlar (som standard är denna rubrik filename.tmh, var filenameär namnet på den bearbetade källfilen). Denna rubrik måste då inkluderas uttryckligen i källfilen, till exempel:

// File: file.cxx
// This file is an example of using WPP
#include "file.tmh"

WPP: s förståelse för C / C ++ syntax är mycket begränsad. I synnerhet utvidgar den inte makron (utom i speciella omständigheter där det är nödvändigt), och hanterar inte heller pragmas eller utför någon semantisk analys.

En utvecklare specificerar en eller flera spårningsmakroer som WPP ska hantera, via en konfigurationsfil, speciella kommentarer i kommentarer, kommandoradsparametrar eller någon kombination av dessa metoder. Varje gång WPP möter en av makronen som den är tänkt att hantera genererar den ett spårmeddelandemakro. Med andra ord, om till exempel DoTraceär ett spårningsmakro, kommer WPP att generera ett separat makro för varje förekomst av DoTrace. De genererade spårmeddelandemakronen är otvetydiga med filnamn och radnummer, och med hjälp av olika preprocessor-tricks definierar WPP i sin tur det ursprungliga spårningsmakroet så att det kommer att utöka rätt spårmeddelandemakro vid varje förekomst.

Hur spårmeddelandemakroer genereras av WPP beror på en mallfil (filens format är odokumenterat). Standardmallfilerna som ingår i WPP anger att strängen i ett spårmeddelande ska inkluderas i en kommentar (med hjälp av __annotationsfunktionen i Microsoft Compiler). Dessa strängar ingår inte i den sammanställda koden, men ingår i felsökningssymbolfilen i ett format som verktyg som ingår i WPP kan förstå. Spårmeddelandets makron innehåller också logiken för att aktivera eller inaktivera spårning via flaggor och samtal till WMI-händelsespårnings-API: er.

begränsningar

  • Eftersom WPP inte expanderar makron känner det inte igen en inställning av ett spårningsmakro som ingår i definitionen av ett annat makro. Till exempel, om DoTraceett spårningsmakro, och ett makro CheckForErrorsdefinieras som:
#define CheckForErrors(error_code) \
    if (IsError(error_code)) \
    { \
        DoTrace("Error %d occurred\n", err); \
        HandleError(error_code); \
    }

då kommer WPP inte att skapa spårmeddelandemakron för DoTracevar som CheckForErrorsinträffar. WPP tillhandahåller en ad hoc-lösning för det här problemet, men det finns fortfarande en liten klass av makron som inte kan uttryckas ens med hjälp av lösningen.

  • Standardmallfilen genererar kod som bara fungerar korrekt med Microsoft-kompilatorn. Även om detta inte är en inneboende begränsning av förbehandlaren, innebär det att mallfilen (som styr vilken kod som genereras i spårmeddelandeshuvudet) använder ett icke-dokumenterat format innebär att WPP i praktiken bara fungerar korrekt med Microsoft-kompilatorn.
  • Tidigare versioner av WPP orsakade kompileringsfel när mer än en spårmakrohuvud inkluderades i en källfil (till exempel om en källfil med spårning inkluderade en rubrik som hade spårning i inlinefunktioner). Detta fixas i den senaste versionen. Observera att detta också är en begränsning av mallfilen, inte själva WPP-verktyget.
  • Eftersom spårmeddelandemakroer är otvetydiga med fil och radnummer kan det bara finnas ett spårningsmakro per rad i källkoden.

externa länkar