FAV-ZCU/KIV PPA1/9. Ověřování správnosti programu, ladění.md

148 lines
9.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Ověřování správnosti programu, ladění
- Při vytváření programů je do zdrojového kódu (neúmyslně) zaneseno mnoho různých chyb od překlepů přes neošetření hraničních případů až po logické chyby v celkovém chování programu
- Část chyb odhalí překladač (a upozorní nás na ně IDE nástroj) chyby při překladu
- Část chyb překladač neodhalí a program jde přeložit
- POZOR!
- Pokud jde program přeložit, neznamená to, že funguje správně!
- Program může (někdy nebo vždy) dávat nesprávné výsledky
- Může docházet k chybám za běhu programu
- Chyby, které překladač neodhalí (chyby za běhu programu), je třeba najít a opravit opakovaným opravováním, překládáním a spouštěním programu s využitím vhodných vstupních dat
- Tato činnost se nazývá ladění (častěji debugging)
- Lze provádět ručně nebo s využitím specializovaného nástroje zvaného debugger součást téměř všech IDE nástrojů
- Často se používá kombinace obou přístupů
- Vyšší fází ladění je testování
- Zjišťuje se, zda program pracuje správně pro všechny typy vstupů, zda reaguje správně na neplatné vstupy apod.
- Podrobně viz předmět KIV/OKS
### Odhalení chyb při psaní zdrojového kódu a při překladu
- Překladač ```javac``` umí odhalit především syntaktické chyby
- Často způsobené překlepy v názvech proměnných, metod, zapomenutím na import třídy, zapomenutím deklarace proměnné, atd.
- Všechny nalezené chyby jsou vypsány při překladu
- Překlad v příkazové řádce
- Pokud překládáme program ručně v příkazové řádce příkazem javac, objevíme chyby až po spuštění překladu
- Protože překlad netrvá dlouho (pro malé programy), je možné provádět ho během vývoje opakovaně, např. při každém inkrementálním přidání funkcionality
- Nalezené chyby lze průběžně odstraňovat
- Odstranění chyby se ověří opakovaným překladem
- Je možné i napsat celý program a poté odstranit chyby najednou
- Odstranění chyb se opět ověří opakovaným překladem
- POZOR!
- Při opakovaném překladu se počty chyb mohou snižovat i zvyšovat
- Překladač se snaží při překladu najít co možná nejvíce chyb tj. neskončí při první nalezené chybě, ale pokud to jde, pokračuje dále
- Některé chyby jsou však z pohledu překladače natolik zásadní (ač z pohledu člověka vypadají banálně např. zapomenutý středník „;“ nebo složená závorka „}“), že mu znemožní kontrolu velké části kódu
- Po opravení takové chyby může překladač tuto přeskočenou část zkontrolovat a tím odhalit další, dosud neodhalené chyby počet chyb může po odstranění chyby vzrůst
#### Čtení a porozumění výstupu překladače
- Výstup překladače (tj. výpis chyb při překladu) se zobrazí po skončení překladu v příkazové řádce nebo v konzoli IDE nástroje
- Výstup nemusí být stejný v IDE a v příkazové řádce
### Ladění (debugging)
- Pokud se **program podaří přeložit**, ještě to **neznamená, že funguje správně**
- Většinou správně nefunguje, i když jde přeložit
- Chyby v chování programu neodhalí překladač, musí je najít sám programátor
- Chybné chování programu se typicky projevuje:
- Program je předčasně ukončen s chybovým hlášením (vždy nebo někdy)
- Je třeba rozumět chybovému hlášení
- Program zdánlivě funguje, ale dává pro některé či všechny vstupy zcela špatné nebo částečně špatné výsledky
- Ladění je možno provádět ručně tzv. metodou ladících výpisů a/nebo s využitím specializovaného ladícího nástroje (debuggeru)
- POZOR!
- Program se nedá považovat za odladěný po vyzkoušení jednoho či několika málo vstupů
- Je potřeba zkoušet více různých vstupních hodnot, netypické hodnoty apod.
- Je potřeba zkoušet i neplatné hodnoty, na něž by měl program adekvátně reagovat
- To však zatím není probráno
#### Chybové hlášení za běhu programu
- Pokud dojde za běhu programu k chybě (přesněji k vyhození výjimky) a tato chyba není v programu ošetřena, program je předčasně ukončen a do konzole (či příkazové řádky) se vypíše chybové hlášení
- Chybové hlášení
- Vypíše, o jakou chybu (výjimku) se jedná (její název a někdy i popis)
- Vypíše tzv. stack trace (výpis zásobníku)
- Zjednodušený obsah zásobníku (stack) programu v okamžiku, kdy k chybě došlo
- Obsahuje volání metod je jasné, v jaké metodě přesně došlo k chybě (první uvedená metoda) a ze které metody byla tato metoda volána (další uvedená metoda)
- Následují další metody, které byly hierarchicky volány až k metodě ```main()```
- V jednoduchých programech je většinou zobrazeno i číslo řádky, na které k chybě došlo
- Hlášení o chybách za běhu programu typicky vypadají stejně v příkazové řádce i v konzoli IDE nástroje
#### Metoda ladících výpisů
- Metoda ladících výpisů se používá, **pokud nemáme k dispozici debugger**, nebo ho z nějakého důvodu nechceme použít
- Na vhodná místa programu vložíme volání metody System.out.println()
- Můžeme vypisovat hodnoty důležitých proměnných
- Můžeme pomocí výpisu unikátních značek (tj. textů) určit, kde se program
- přesně nachází (podle toho, co a v jakém pořadí program vypíše)
#### Použití debuggeru v Eclipse
- Debugger umožňuje dělat automaticky to, co musíme ručn pomocí kontrolních výpisů a umožňuje mnohem více
- Sledování hodnot vybraných proměnných a výrazů
- Krokování programu řádku po řádce
- Nastavení breakpointů bodů, ve kterých se program zastaví a umožní od něj krokování
- Spuštění debuggeru v Eclipse
- Vytvoření breakpointu
- Pro zapnutí debuggeru je potřeba nastavit breakpoint, tedy bod, od kterého bude program krokován
- Breakpoint se na určitou řádku nastaví dvojklikem vlevo od požadované řádky
- Alternativou je kliknout pravým tlačítkem na stejné místo => vybrat Toogle breakpoint
- Přítomnost breakpointu na řádce je indikována symbolem
- Stejným způsobem lze breakpoint odstranit
- Spuštění debuggeru
- Mít aktivní třídu s breakpointem
- Debug as… => Java Application
- Pokud si Eclipse není jistý, který program chcete debuggovat, dá vám na výběr
- Pokud není zvolen žádný breakpoint, program proběhne jako při normálním spuštění
- Po spuštění debuggeru program běží normálně, dokud nedosáhne breakpointu
- Potom se objeví dotaz, zda chceme spustit debug perspektivu, která přepne rozložení oken Eclipse
- Popis debug perspektivy v Eclipse
- Okno zásobníku
- Ukazuje, v jaké části programu se právě nacházíme
- Jde o zobrazení části paměti zásobník obsahující rámce pro jednotlivé volání metod
- Toto okno příliš nevyužíváme
- Okno editoru
- Okno se zdrojovým kódem
- V debug perspektivě se zpravidla nepoužívá pro úpravu kódu
- Zelený pruh určuje řádku, na které se program právě nachází při jeho krokování
- Jsou vidět nastavené breakpointy
- Nejdůležitější okno debuggeru
- Okno se strukturou programu (outline)
- Zobrazuje strukturu programu (jednotlivé třídy a metody)
- Toto okno příliš nevyužíváme
- Okno konzole
- Okno, do kterého se vypisuje výstup programu
- Uživatel zde rovněž zadává vstup programu, pokud je třeba
- Okno sledování proměnných
- Zde můžeme sledovat všechny proměnné a jejich aktuální hodnoty během krokování programu
- Druhé nejdůležitější okno debuggeru
- V záložce Breakpoints je seznam všech nastavených breakpointů
- Ovládání debuggeru
- V okamžiku, kdy se program zastaví na breakpointu, lze pokračovat v jeho krokování různými způsoby
- Step Into - též klávesa [F5]
- Provede jeden krok programu
- Pokud je tímto krokem volání metody, skočí do této metody
- Step Over též klávesa [F6]
- Provede jeden krok programu
- Pokud je tímto krokem volání metody, provede ji celou jako jeden krok (tj. do metody neskočí)
- Step Return též klávesa [F7]
- Provede všechny zbývající příkazy v metodě, vyskočí z ní a zastaví se na dalším řádku volající metody
- Resume též klávesa [F8]
- Provede všechny příkazy od aktuální pozice až k dalšímu breakpointu (nebo do ukončení programu) normálně (tj. bez krokování)
- Terminate též [Ctrl]+[F2]
- Ukončí provádění programu
- Nastavení filtrů krokování (step filters)
- Umožní omezit, do kterých metod je možné při krokování skočit
- Např. nechceme, abychom se při krokování dostali do knihovních tříd a metod Java Core API
- Zapnutí filtrů krokování (Use Step Filters též [Ctrl]+[F5])
- Pokud je tlačítko zapnuté, filtry jsou použity a do vybraných balíků nevstoupí ani možnost Step Into
- Sledování hodnot proměnných (okno sledování proměnných)
- Záložka Variables
- Automaticky zobrazuje platné lokální proměnné a jejich hodnoty
- Pro zobrazení statických proměnných a konstant je nutné je zaškrtnout
- => Java => Show Constants a Show Static Variables
- Zobrazení aktuální hodnoty proměnné
- Stačí kurzorem myši najet v okně editoru na proměnnou, která nás zajímá
- Díky debuggeru přesně vidíme, co se v programu děje, jaké jsou hodnoty proměnných
- Podstatně komfortnější, než kontrolní výpisy
- Lze vyzkoušet na odhalení chyb v programu pro výpočet faktoriálu