Preprocesor de urmărire software pentru Windows - Windows software trace preprocessor
Pentru Windows software - ul de urmărire preprocesorul ( WPP , preprocesorul și instrumente de sprijin conexe sunt cunoscute ca WPP Software Tracing ) este un preprocesor care simplifică utilizarea WMI eveniment de urmărire pentru punerea în aplicare eficientă a software - ului de urmărire în drivere și aplicații care vizează Windows 2000 și sistemele de mai târziu de operare. WPP a fost creat de Microsoft și este inclus în DDK Windows . Deși WPP este larg în aplicabilitatea sa, acesta nu este inclus în SDK-ul Windows și, prin urmare, este utilizat în principal pentru driverele și software-ul de asistență pentru drivere produse de furnizorii de software care achiziționează Windows DDK.
fundal
Urmărirea software-ului este o utilizare specializată a jurnalului pentru a înregistra informații despre execuția unui program. Aceste informații sunt utilizate în mod obișnuit pentru depanare . Spre deosebire de înregistrarea de evenimente , al cărui scop principal este de a produce înregistrări ale evenimentelor care pot fi auditate de către administratorii de sistem (a se vedea, de exemplu, Event Viewer ) sau analizate prin instrumente de management, urmărirea software este în primul rând un ajutor de depanare pentru dezvoltatorii de software . Ca atare, multe dintre cerințele nefuncționale ale înregistrării de evenimente, cum ar fi localizabilitatea sau un format de ieșire bazat pe standarde , sunt în mod explicit non-obiective pentru majoritatea aplicațiilor de urmărire software. Pe de altă parte, urmărirea software are cerințe speciale pentru performanțe care nu sunt, în general, la fel de importante în înregistrarea evenimentelor. De exemplu, o utilizare obișnuită a urmăririi software, urmărirea în / out , produce ieșire la punctul de intrare și retur de funcții sau metode, astfel încât un dezvoltator să poată urmări vizual calea de execuție, incluzând adesea parametri și valori de retur , într-un debugger sau un text. - fișier jurnal bazat (acesta poate fi văzut ca un analog de timp de rulare al unei diagrame de secvență ). Acest tip de urmărire, deși este util pentru dezvoltatori, poate afecta foarte mult performanța unui produs software dacă nu poate fi dezactivat (fie la compilare prin compilare condiționată, fie în timp de rulare prin steaguri ).
Considerații suplimentare speciale pentru urmărirea software includ următoarele:
- În software-ul proprietar , urmărirea datelor poate include informații sensibile despre codul sursă al produsului .
- Dacă urmărirea este activată sau dezactivată la timpul de execuție, multe metode de urmărire necesită o cantitate semnificativă de date suplimentare incluse în binar, ceea ce poate afecta indirect performanța chiar și atunci când urmărirea este dezactivată.
- Dacă urmărirea este activată sau dezactivată la timp de compilare, obținerea de date de urmărire pentru o problemă pe o mașină client depinde de faptul că clientul este dispus și capabil să instaleze o versiune specială a software-ului dvs..
- Anumite tipuri de software, cum ar fi driverele, trebuie să îndeplinească cerințe de performanță stricte, chiar și cu activarea urmăririi.
Datorită primelor două considerente, metodele tradiționale de urmărire a software-ului folosesc compilarea condiționată pentru a activa sau dezactiva urmărirea (și includerea datelor de urmărire) în timp de compilare. De exemplu, folosind preprocesorul C , se poate defini o macro DebugOutdupă cum urmează:
#ifdef _DEBUG
#define DebugOut(msg, ...) \
DebugPrintf(__FUNCTION__ "(" __FILE__ ":" TO_STRING(__LINE__) ")\t" \
msg, __VAR_ARGS__)
#else
#define DebugOut(msg, ...)
#endif
în cazul în care TO_STRINGeste un macro care convertește numărul liniei ( __LINE__) la un șir de caractere și DebugPrintfeste o printf -ca funcție care ar putea , de exemplu , textul de ieșire la debugger.
Apoi, următorul cod:
DebugOut("Error %d occurred\n", error_code);
ar produce o ieșire similară cu cea următoare în cazul compilărilor de depanare:
SomeFunction(file.c:78) Error 217 occurred
O altă tehnică pentru anumite tipuri de urmărire (în special în urmărirea / ieșirea) este utilizarea instrumentației . Deși această tehnică poate aborda multe dintre problemele majore, aceasta nu este întotdeauna disponibilă (de obicei numai în cod gestionat ).
Urmărirea evenimentelor WMI este un exemplu de tehnologie care abordează îndeosebi performanțele de urmărire în codul critic pentru performanță, cum ar fi driverele. De asemenea, poate aborda preocuparea de a controla distribuția informațiilor de urmă sensibile, lăsând un dezvoltator să definească datele de urmărire care pot fi citite de oameni ( "Error %d occurred\n"în exemplul de mai sus) separat de cod, astfel încât să nu fie încorporate în produs (în cod, la mesajul specific se face referire prin numărul mesajului său). Cu toate acestea, există câteva limitări importante:
- Urmărirea evenimentelor WMI nu poate, de la sine, să genereze automat
"SomeFunction(file.c:78)"partea din mesajul de urmă. Aceasta este o limitare a tuturor acestor tehnologii, nu specifică urmăririi evenimentelor WMI. - Solicitarea părții care poate fi citită de om din datele de urmărire să fie separată de cod poate reduce lizibilitatea codului.
- Utilizarea acestei tehnici poate introduce o dezvoltare semnificativă a aerului pentru mesajele de urmărire „cu o singură poză”.
Funcționarea WPP
WPP este rulat înainte de compilare (cu alte cuvinte, înainte chiar de preprocesorul C) și generează un antet de mesaj de urmărire pentru fiecare fișier pe care îl prelucrează (implicit acest antet este filename.tmh, unde filenameeste numele fișierului sursă procesat). Acest antet trebuie să fie inclus în mod explicit în fișierul sursă, de exemplu:
// File: file.cxx // This file is an example of using WPP #include "file.tmh"
Înțelegerea WPP despre sintaxa C / C ++ este foarte limitată. În special, nu extinde macro-urile (cu excepția unor circumstanțe speciale în care este necesar) și nici nu se ocupă de pragme sau nu realizează nicio analiză semantică.
Un dezvoltator specifică una sau mai multe macro-uri de urmărire pe care WPP ar trebui să le gestioneze, printr-un fișier de configurare, adnotări speciale în comentarii, parametri ai liniei de comandă sau o combinație a acestor metode. De fiecare dată când WPP întâlnește una dintre macro-urile pe care se presupune că le gestionează, generează o macro-mesaj de urmărire. Cu alte cuvinte, dacă, de exemplu, DoTraceeste o macrocomandă, WPP va genera o macrocomandă separată pentru fiecare apariție a DoTrace. Macro-urile de mesaj de urmărire generate sunt dezambigurate după numele fișierului și numărul de linie și, folosind diferite trucuri de preprocesor, WPP la rândul său definește macro-ul de urmărire original, astfel încât va extinde macro-ul de mesaj de urmărire corespunzător la fiecare apariție.
Modul în care macro-urile de mesaje sunt generate de WPP depinde de un fișier șablon (formatul fișierului nu este documentat). Fișierele de șablon implicite incluse cu WPP specifică faptul că șirul unui mesaj de urmărire ar trebui inclus într-o adnotare (folosind caracteristica __annotare a compilatorului Microsoft). Aceste șiruri nu sunt incluse în codul compilat, dar sunt incluse în fișierul de simboluri de depanator într-un format pe care instrumentele incluse cu WPP îl pot înțelege. Macro-urile de mesaje de urmărire includ, de asemenea, logica pentru activarea sau dezactivarea urmăririi prin steaguri și apelurile către API-urile de urmărire a evenimentelor WMI.
limitări
- Deoarece WPP nu extinde macro-urile, nu va recunoaște o instantanare a unei macro-uri de urmărire care este inclusă în definiția altei macro-uri. De exemplu, dacă
DoTraceeste o macrocomentare, și o macroCheckForErrorseste definită ca:
#define CheckForErrors(error_code) \
if (IsError(error_code)) \
{ \
DoTrace("Error %d occurred\n", err); \
HandleError(error_code); \
}
atunci WPP nu va genera macro-urile de urmărire pentru DoTracelocul unde CheckForErrorsapare. WPP oferă o soluție ad-hoc pentru această problemă, dar există încă o clasă mică de macro-uri care nu pot fi exprimate chiar și folosind soluția.
- Fișierul șablon implicit generează cod care va funcționa corect numai cu compilatorul Microsoft. Deși aceasta nu este o limitare inerentă a preprocesorului, faptul că fișierul șablon (care controlează ce cod este generat în antetul mesajului de urmărire) folosește un format nedocumentat înseamnă că, în practică, WPP va funcționa corect numai cu compilatorul Microsoft.
- Versiunile anterioare ale WPP au cauzat erori de compilare atunci când mai mult de un antet macro urmă au fost incluse într-un fișier sursă (de exemplu, dacă un fișier sursă cu urmărire a inclus un antet care avea urmărirea în funcțiile inline). Aceasta este rezolvată în cea mai recentă versiune. Rețineți că aceasta este, de asemenea, o limitare a fișierului șablon, nu instrumentul WPP în sine.
- Deoarece macro-urile de mesaje de urmărire sunt deambigurate de fișier și număr de linie, în codul sursă poate exista doar o singură macro de urmărire.