|| Home || IT Security || Smart cards || Resources || Links || switch_to_cz

Ukazky ladeni programu ve Visual Studiu

Posledni aktualizace: 14.10.2009



Nejprve spustime Visual Studio a vytvorime novy projekt, viz Vyvoj programu C++ v kombinaci Visual Studio 2005 a Unix (aisa). Program musi byt korektne prelozitelny.



Vlozime breakpoint na cilove misto v programu pomoci kliku na cilovy radek a klavesy F5.



Spustime ladeni aplikace. Dojde ke spusteni aplikace (ktera tedy musi byt kompilovatelna) a jeji beh se zastavi na prvnim breakpointu, na ktery se narazi.



Aplikace se zastavila a lze provadet ladeni. V nasem pripade jde o konzolovou aplikace, takze je zobrazeno i konzolove okno. Aktualni misto v behu programu je oznaceno zlutou sipkou.



Hodnoty promennych v aktualnim kontextu (funkce ve ktere se nachazite apod.) naleznete typicky vlevo dole v zalozce Autos. Vypisovane promenne se ale budou lisit podle mista, kde zrovna jste.



Pro trvale zobrazeni promenne vlozte jeji nazev do zalozky Watch.



Rychle zobrazeni obsahu promenne udelate najetim kurzoru na cilovou promennou.



Promennou do zalozky Watch muzete pridat i pres nabidku pod pravym mysitkem - nemusite vypisovat jeji nazev.



Nyni muzeme provest jeden krok programu. Pokud pouzijeme StepOver (F10) program se zastavi na dalsim radku. Pokud na aktualnim radku byla volana nejaka funkce, funkce se cela provede a ladeni nevstupuje do tela teto funkce.



Opakovanym stiskem F10 postupujeme ladenym programem. Pokud se narazi na radek, kde je ocekavan vstup od uzivatele, tak se ladeni docasne prerusi a tento vstup je v konzoli nutne zadat.



Pokud chceme vstoupit pri ladeni do tela funkce, je nutne na prislusnem radku pouzit StepInto (F11) namisto StepOver (F10). Program nepokracuje na dalsim radku aktualniho kodu, ale vstupi do kodu vykonavane podfunkce, zde funkce fakt().



Pri ladeni slozitejsiho programu snadno ztratime predstavu, kde presne v kodu se nachazime a jaka sekvence zanoreni funkci zpusobila aktualni pozici programu v kodu (napr. proto, ze umistime breakpoint, na nem dojde k zastaveni behu programu a my nyni chceme zjistit, ktere funkce vedly k dosazeni naseho breakpointu). K tomu vyuzijeme zalozku Call stack (vpravo dole). Obsahuje zasobnik volani jednotlivych funkce dle urovne zanoreni. Nahore se nachazi aktualni pozice v kodu (tam kde je nas breakpoint a program stoji a ceka na nase ladeni) az po nejvnejsnejsi metodu (nas typicky bude zajimat volani po uroven metody main() - dalsi predchozi metody vetsinou patri operacnimu systemu a jsou zvyrazneny sede). Dvojklikem na libovolnem polozku na zasobniku volani se nam zobrazi kod v miste tohoto volani - velmi prakticke.



Pri vlozeni standardniho breakpointu se beh aplikace zastavi pokazde, kdyz je dosazeno radku, na kterem je breakpoint umisten (bezpodminecny breakpoint). Toto chovani muze byt v nketreych pripadech nezadouci. Predstavme si cyklus, ktery probehne celkove 1000x a nas zajima stav vnitrnich hodnot pri 840 iteraci. Bezpodminecny breakpoint je zde nepouzitelny, protoze by trvalo velmi dlouho, nez bychom se dostali do 840 iterace. Dalsim pripadem je situace, kdy chceme zastavit vevnitr cyklu az na zaklade konkretni hodnoty promenne (zde f) a nevime, kdy takova situace nastane. pro toto pouziti se hodi podmineny breakpoint. Nejprve vlozime standardni breakpoint (nepodmineny) F9 a volbou pres prave mysitko vybereme typ podminky pro breakpoint - nyni Condition.



Zadane libovolny platny logicky vyraz, jehoz splneni se bude testovat a aplikace se zastavi na podminenem breakpointu teprve v pripade, ze je podminka splnena. Zde chceme zastavit ve chvili, kdy bude f vetsi nez 330. Na ikone breakpointu pribude bily krizek znacici podmineny breakpoint. Vsimnete si, ze kod cyklu se oproti predchozimu obrazku mirne zmenil - namisto cyklu
for(int i=n; i>0; i--) f*=i;
je cyklus rozepsan na vice radku (bez zmeny jeho obsahu):
for(int i=n; i>0; i--) {
    f*=i;
}
Tato uprava je nutna z toho duvodu, ze breakpoint (podmineny i nepodmineny) se vztahuje na prvni vyraz zleva na radku. Pokud umistime breakpoint na radek obsahujici cely cyklus na jedinem radku, tak se jeho umisteni vztahuje pouze na pocatecni inicializaci ridici promenne cyklu (int i=n;) a nikoli telo cyklu obsahujici pro nas zajimavy vyraz f*=i;. Podmineny breakpoint nastaveny na hodnotu f > 330 tak neni nikdy vyhdnocen jako platny a aplikace by na takovem breakpointu nikdy nezastavila.



Pokud mame aplikaci v ladicim rezimu zastavenou na konkretnim radku a nechceme dal pokracovat skakanim po jednotlivych radcich (F10 nebo F11), ale chceme nechat program bezet az dalsiho breakpointu (podmineneho nebo nepodmineneho), zvolime prikaz Continue (F5).



Nyni se nam aplikace zastavila diky podminenemu breakpointu, nebot byla prekrocena hodnota 330 v promenne f. Jeji aktualni hodnotu si muzeme zobrazit v Autos, jako polozku ve Watch nebo najetim kurzoru na promennou. Zaroven si muzeme otestovat, jaka byla jeji hodnota v minulem cyklu - i do zalozky Watch muzeme vkladat nejenom jmena promennych, ale cele vyrazy (zde f / (i+1), nebot hodnota ridici promenne i cyklu byla v predchozi iteraci o jedna vetsi.)



Do teto chvile jsme nevyuzili moznosti, ze beh programu muze byt ovlivnen parametry zadanymi na prikazove radce. Pro ucely ladeni muzeme tyto parametry pro aplikaci nastavit. Vstoupime do nastaveni projektu (Alt+F7).



V nastaveni Configuration properties -> Debugging nastavime polozku Command arguments na hodnotu prikazove radky. (Pokud by tedy byl program spousten z prikazove radky s parametrem 25 pro vypocet faktorialu - 'cv1.exe 25' (Win) nebo './cv1 25' (unix), tak nastavime parametr na 25. Muzeme samozrejme zadat vice parametru oddelenych mezerou vcetne textovych retezcu.



Po nastaveni prikazove radky ladeneho programu umistime breakpoint na radek testovani hodnoty argc (if (argc > 1) {) a aplikaci spustime. Po zastaveni snadno overime, ze parametr 25 byl programu predan a hodnota argc se zmenila na 2 (jmeno programu + jeden parametr). Ukazkovy program pak prijme vstup z prikazoveho radku namisto vypisu vyzvy zadani pro uzivatele.



Obsah zvolene promenne muzeme behem ladeni menit. Tato moznost muze byt vyhodna v pripade, ze chceme vyzkouset hodnotu, kterou je obtizne v promenne ziskat beznym behem aplikace, chceme pokracovat v ladeni programu, prestoze nastala chyba, ktera by jinak zpusobila jeho ukonceni apod. Vychozi hodnota promenne cislo je 25.



Nejprve pridame cilovou promennou do zalozky Watch a nasledne dvojklikem na hodnotu promenne (zde 25 v promenne cislo) prepiseme na nami zvolenou hodnotou. Po zadani hodnoty je nutne enterem potvrdit zmenu, jinak k ni nedojde. Typicky lze takto modifikovat jednoduche datove typy jako cisla, logicke promenne a obsah poli. Retezce lze modifikovat obtizneji, predevsim pokud jsou v STL objektu typu string (obecne se nedoporucuje takovou zmenu delat, pokud opravdu nevite co delate - slozitejsi objekty maji typicky aktualizuji stav svych vnitrnich promennych konzistentnim zpusobem a zmenou jednoho parametru se muze objekt dostat do nekonzistentniho stavu, nebot nebyla zaroven aktualizovana hodnota jinych zavislych promennych).



To je pro zacatek vse, ladeni timto zpusobem byva vyrazne rychlejsi pro nalezeni chyby, nez pouziti ladicich vystupu na terminal a podobne. Presto ale muze mit omezeni v pripade, ze v ladicim rezimu nedochazi k vyskytu nekterych chyb (napr. z duvodu mirne odlisneho prelozeni kodu ) nebo nemoznosti pustit aplikaci v ladicim rezimu na realnych datech. Kazdopadne je ale interaktivni ladeni mocny nastroj, ktery usetri spoustu casu a je dobre naucit se ho ovladat (neni to tak komplikovane).

  1. Zakladni kroky pri ladeni, nastaveni Visual Studia.
  2. Nastaveni prikazove radky.
  3. Ladeni s modifikaci aktualni hodnoty promenne.
  4. Ladeni s vyuzitim podminenych breakpoints.
  5. Ladeni s detekci zmeny v pameti.
  6. Ladeni s vyuzitim disassembleru.


Pokud narazite na jakykoli relevantni problem, budu vam vdecen za jeho popis (kontakt je na konci stranky). Diky!



contact
OpenPGP key : 0x89CEB31C