Cvičení – ladění pomocí editoru Visual Studio Code

Dokončeno

Je čas dát nově získané znalosti ladění do praxe. Jste první den v práci a máte použít své schopnosti ladění programů platformy .NET a opravit chybu v důležitém firemním produktu – Fibonacciho kalkulačce.

Vytvoření ukázkového projektu platformy .NET pro ladění

K nastavení editoru Visual Studio Code pro ladění programů platformy .NET budeme nejprve potřebovat projekt platformy .NET. Visual Studio Code obsahuje integrovaný terminál, který usnadňuje vytváření nového projektu.

  1. V nástroji Visual Studio Code vyberte File (Soubor)>Open Folder (Otevřít složku).

  2. Vytvořte novou složku s názvem DotNetDebugging ve zvoleném umístění. Pak zvolte Vybrat složku.

  3. Ve Visual Studio Code otevřete integrovaný terminál výběrem View (Zobrazit) >Terminal (Terminál) z hlavní nabídky.

  4. V okně terminálu zkopírujte a vložte následující příkaz:

    dotnet new console
    

    Tento příkaz vytvoří ve vaší složce soubor Program.cs, který obsahuje základní hotový program „Hello World“. Vytvoří také soubor projektu v jazyce C# s názvem DotNetDebugging.csproj.

  5. V okně terminálu zkopírujte a vložte následující příkaz a spusťte tak program „Hello World“.

    dotnet run
    

    V okně terminálu se jako výstup zobrazí Text Hello World.

Nastavení editoru Visual Studio Code pro ladění programů platformy .NET

  1. Otevřete soubor Program.cs tím, že ho vyberete.

  2. Když v editoru Visual Studio Code poprvé otevřete nějaký soubor v jazyce C#, zobrazí se vám výzva k instalaci doporučených rozšíření pro jazyk C#. Pokud se vám tato výzva zobrazí, vyberte tlačítko Install (Nainstalovat) ve výzvě.

    Screenshot of Visual Studio Code prompt to install the C# extension.

  3. Visual Studio Code nainstaluje rozšíření jazyka C# a zobrazí další výzvu k přidání požadovaných prostředků pro sestavení a ladění projektu. Vyberte tlačítko Yes (Ano).

    Screenshot of Visual Studio Code prompt to add required assets to build and debug your .NET project.

  4. Kartu Rozšíření: C# můžete zavřít a zaměřit se na kód, který budeme ladit.

Přidání logiky Fibonacciho programu

Náš současný projekt vypisuje do konzoly zprávu „Hello World“, takže nemáme moc co ladit. Místo toho použijete krátký program platformy .NET k výpočtu čísla N ve Fibonacciho posloupnosti.

Fibonacciho posloupnost je sada čísel začínající čísly 0 a 1, přičemž každé další číslo vznikne součtem dvou předchozích čísel. Tato posloupnost pokračuje takto:

0, 1, 1, 2, 3, 5, 8, 13, 21...
  1. Otevřete soubor Program.cs tím, že ho vyberete.

  2. Obsah souboru Program.cs nahraďte tímto kódem:

    int result = Fibonacci(5);
    Console.WriteLine(result);
    
    static int Fibonacci(int n)
    {
        int n1 = 0;
        int n2 = 1;
        int sum;
    
        for (int i = 2; i < n; i++)
        {
            sum = n1 + n2;
            n1 = n2;
            n2 = sum;
        }
    
        return n == 0 ? n1 : n2;
    }
    

    Poznámka:

    Tento kód obsahuje chybu, kterou budeme ladit později v tomto modulu. Nedoporučujeme, abyste ho používali v jakýchkoli důležitých Fibonacciho aplikacích, dokud tuto chybu neopravíme.

  3. Ve Windows nebo Linuxu soubor uložte stisknutím kláves CTRL+S. Pokud používáte Mac, stiskněte klávesyCmd+S.

  4. Pojďme se podívat, jak aktualizovaný kód funguje, než ho budeme ladit. Spusťte program zadáním následujícího příkazu v terminálu:

    dotnet run
    

    Terminal window with modified program output.

  5. Výsledek 3 se zobrazí ve výstupu terminálu. Když si projdete tento fibonacciho sekvenční graf, který zobrazuje pozici sekvence na základě nuly pro každou hodnotu v závorkách, uvidíte, že výsledek by měl být 5. Teď se seznámíme s ladicím programem a tento program opravíme.

    0 (0), 1 (1), 1 (2), 2 (3), 3 (4), 5 (5), 8 (6), 13 (7), 21 (8)...
    

Analýza problémů

  1. Spusťte program tak , že na levé straně vyberete kartu Spustit a ladit a pak vyberete tlačítko Spustit ladění .

    Screenshot of the Start debugging button in Visual Studio Code.

    Program by se měl dokončit rychle. To je normální, protože jste zatím nepřidali žádné zarážky.

  2. Pokud se konzola ladění nezobrazí, vyberte Kombinaci kláves Ctrl+Shift+Y pro Windows a Linux nebo Cmd+Shift+Y pro Mac. Měli byste vidět několik řádků s diagnostickými informacemi, na jejichž konci jsou tyto řádky:

    ...
    Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0\System.Threading.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
    Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0\System.Text.Encoding.Extensions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
    3
    The program '[88820] DotNetDebugging.dll' has exited with code 0 (0x0).
    

Na řádcích v horní části se dozvíte, že výchozí nastavení ladění povoluje funkci „Just My Code“ (Pouze můj kód). To znamená, že ladicí program bude ladit pouze váš kód a nebude krokovat do zdrojového kódu pro .NET, pokud tento režim nezakážete. Tato možnost vám dovoluje se soustředit na ladění vašeho kódu.

Na konci výstupu konzoly ladění uvidíte, že program vypíše do konzoly hodnotu 3 a pak se ukončí s kódem 0. Ukončovací kód programu 0 obvykle znamená, že program běžel a skončil bez chybového ukončení. Mezi chybovým ukončením a vrácením správné hodnoty je však rozdíl. V tomto případě jsme program požádali o výpočet páté hodnoty Fibonacciho posloupnosti:

0 (0), 1 (1), 1 (2), 2 (3), 3 (4), 5 (5), 8 (6), 13 (7), 21 (8)...

Pátou hodnotou v tomto seznamu je číslo 5, ale náš program vrátil číslo 3. Pojďme k diagnostice a opravě této chyby použít ladicí program.

Použití zarážek a krokování

  1. Přidejte zarážku kliknutím na levý okraj na řádku 1 na int result = Fibonacci(5);.

    Screenshot of the breakpoint location in the code.

  2. Znovu spusťte ladění. Program se začne vykonávat. Přeruší (pozastaví provádění) na řádku 1 kvůli nastavené zarážce. Pomocí ovládacích prvků ladicího programu proveďte krokování s vnořením do funkce Fibonacci().

    Screenshot of the Step into button.

Kontrola stavu proměnných

Teď se chvíli věnujte kontrole hodnot různých proměnných na panelu Variables (Proměnné).

Screenshot of the Variables panel.

  • Jaká se zobrazuje hodnota parametru n?
  • Jaké jsou na začátku provádění této funkce hodnoty místních proměnných n1, n2 a sum?
  1. Pak přejdeme do smyčky for pomocí ovládacího prvku ladicího programu Step Over (Krok přes).

    Screenshot of the Step over button.

  2. Postupujte dál, dokud se nedostanete k prvnímu řádku uvnitř smyčky for, a to na následující řádek:

    sum = n1 + n2;
    

Poznámka:

Možná jste si všimli, že přechod na řádek for(...) {} vyžaduje více příkazů s kroky dovnitř. K tomu dochází, protože na tomto řádku existuje více příkazů. V rámci krokování přejdete na další příkaz ve vašem kódu. Obvykle je na řádku jen jeden příkaz. Pokud tomu ale tak není, potřebujete pro přechod na další řádek více kroků.

Rozbor kódu

Důležitou součástí ladění je to, že se zastavíte a zkusíte odhadnout, co se podle vás snaží části kódu (funkce i bloky, jako jsou smyčky) dělat. Pokud si nejste jistí, je to v pořádku – to je součástí procesu ladění. Když však budete v procesu ladění aktivně zapojení, pomůže vám to najít chyby mnohem rychleji.

Než budeme pokračovat dál, připomeneme si, že Fibonacciho posloupnost je řada čísel začínající čísly 0 a 1, přičemž každé další číslo vznikne součtem dvou předchozích čísel.

To znamená, že:

Fibonacci(0) = 0
Fibonacci(1) = 1
Fibonacci(2) = 1 (0 + 1)
Fibonacci(3) = 2 (1 + 1)
Fibonacci(4) = 3 (1 + 2)
Fibonacci(5) = 5 (2 + 3)

Když porozumíme této definici a podíváme se na smyčku for, můžeme odvodit následující:

  1. Smyčka počítá od čísla 2 do čísla n (číslo ve Fibonacciho posloupnosti, které hledáme).
  2. Pokud je n menší než 2, smyčka se nespustí. Příkaz return na konci funkce vrátí hodnotu 0, pokud n je 0, a hodnotu 1, pokud n je 1 nebo 2. To je z definice nultá, první a druhá hodnota ve Fibonacciho posloupnosti.
  3. Zajímavější případ nastane, když je n větší než 2. V těchto případech je aktuální hodnota definována jako součet předchozích dvou hodnot. Takže pro tuto smyčku jsou n1 a n2 předchozí dvě hodnoty a sum je hodnota aktuální iterace. Z tohoto důvodu se pokaždé, když zjistíme součet předchozích dvou hodnot a provedeme u něho funkci sum, aktualizují hodnoty n1 a n2.

V pořádku, dál nad tím nemusíme přemýšlet. Můžeme se trochu věnovat ladicímu programu. Je ale vhodné rozebrat kód a podívat se, jestli dělá to, co očekáváme, a zjistit více, pokud to nedělá.

Vyhledání chyby pomocí zarážek

Procházení kódu může být užitečné, ale zdlouhavé, zejména když pracujete se smyčkami nebo jiným kódem, který se volá opakovaně. Místo toho, abychom smyčku opakovaně procházeli, můžeme na prvním řádku smyčky nastavit novou zarážku.

Při umísťování zarážek je důležité postupovat strategicky. Zajímá nás zejména hodnota sum, protože představuje aktuální maximální Fibonacci hodnotu. Z tohoto důvodu umístíme zarážku na řádek posum nastavení.

  1. Přidejte druhou zarážku na řádku 13.

    Screenshot showing a second breakpoint being set.

    Poznámka:

    Pokud si všimnete, že kód spouštíte a pak procházíte další jeden nebo dva řádky, můžete zarážky snadno aktualizovat na vhodnější řádky.

  2. Když teď máme ve smyčce dobře nastavené zarážky, budeme k postupu používat ovládací prvek ladicího programu Continue (Pokračovat), který se u zarážky vždy zastaví. Když se podíváme na místní proměnné, uvidíme následující řádky:

    n [int]: 5
    n1 [int]: 0
    n2 [int]: 1
    sum [int]: 1
    i [int]: 2
    

    Všechny tyto řádky vypadají správně. Při prvním průchodu smyčkou je součet sum předchozích dvou hodnot 1. Místo krokování po jednotlivých řádcích můžeme využít naše zarážky a přejít k dalšímu průchodu smyčkou.

  3. Výběrem možnosti Continue (Pokračovat) pokračujte v provádění programu, dokud nedojde k další zarážce, která bude u dalšího průchodu smyčkou.

    Poznámka:

    Nemusíte se moc obávat, že při používání možnosti Continue (Pokračovat) chybu přeskočíte. Smiřte se s tím, že kód budete často ladit několikrát, než problém najdete. Často je rychlejší kód několikrát spustit místo toho, abyste ho opatrně pomalu krokovali.

    Tentokrát uvidíme následující hodnoty:

    n [int]: 5
    n1 [int]: 1
    n2 [int]: 1
    sum [int]: 2
    i [int]: 3
    

    Zkusme se zamyslet. Dávají tyto hodnoty stále smysl? Vypadá to tak. U třetího Fibonacciho čísla očekáváme, že se bude součet sum rovnat číslu 2. To platí.

  4. Pojďme tedy vybrat Continue (Pokračovat) a projít smyčku znovu.

    n [int]: 5
    n1 [int]: 1
    n2 [int]: 2
    sum [int]: 3
    i [int]: 4
    

    Znovu to vypadá dobře. Čtvrtou hodnotou v posloupnosti by mělo být číslo 3.

  5. V tomto okamžiku se sami sebe začnete ptát, jestli kód není celou dobu správný a tuto chybu jste si nevymysleli. Pojďme projít smyčkou ještě jednou naposledy. Ještě jednou vyberte Continue (Pokračovat).

    Moment! Program se dokončil a vytiskl hodnotu 3! To je špatně.

    Nevadí, není potřeba se tím trápit. Neselhali jsme, něco jsme zjistili. Nyní víme, že kód prochází smyčkou správně do chvíle, kdy se hodnota i rovná 4, ale před výpočtem konečné hodnoty se ukončí. Začínám mít představu o tom, kde je chyba. Jsi ty?

  6. Pojďme nastavit jednu další zarážku na řádku 17, která čte:

    return n == 0 ? n1 : n2;
    

    Tato zarážka nám umožní zkontrolovat stav programu předtím, než se funkce ukončí. Už jsme se naučili vše, co můžeme očekávat od předchozích zarážek na řádcích 1 a 13, abychom je mohli vymazat.

  7. Odeberte předchozí zarážky na řádcích 1 a 13. Můžete to udělat tak, že na ně kliknete na okraji vedle čísel řádků nebo zrušíte zaškrtnutí políček zarážek pro řádky 1 a 13 v podokně Zarážky v levém dolním rohu.

    Screenshot showing the breakpoints listed in the Breakpoints pane.

    Když teď o moc lépe rozumíme tomu, co se děje, a nastavili jsme zarážku určenou k zachycení nesprávného fungování našeho programu, měli bychom být schopni tuto chybu zachytit.

  8. Naposledy spusťte ladicí program.

    n [int]: 5
    n1 [int]: 2
    n2 [int]: 3
    sum [int]: 3
    

    Tak to je špatně. Konkrétně jsme vyžádali Fibonacci(5) a dostali jsme Fibonacci(4). Tato funkce vrací n2, přičemž každá iterace smyčky počítá hodnotu sum a n2 nastaví na sum.

    Na základě těchto informací a našeho předchozí ladění vidíme, že se smyčka ukončila, když hodnota i byla 4, a ne 5.

    Pojďme se blíže podívat na první řádek smyčky for.

    for (int i = 2; i < n; i++)
    

    Tak moment! To znamená, že se ukončí, jakmile horní část smyčky uvidí, že i již není menší než n. A to znamená, že se kód smyčky nespustí v případě, že i je rovno n. Vypadá to, že kód by spíše měl běžet až do chvíle, kdy platí i <= n:

    for (int i = 2; i <= n; i++)
    

    Když v programu tuto změnu provedeme, měl by vypadat jako tento příklad:

    int result = Fibonacci(5);
    Console.WriteLine(result);
    
    static int Fibonacci(int n)
    {
        int n1 = 0;
        int n2 = 1;
        int sum;
    
        for (int i = 2; i <= n; i++)
        {
            sum = n1 + n2;
            n1 = n2;
            n2 = sum;
        }
    
        return n == 0 ? n1 : n2;
    }
    
  9. Pokud jste to ještě neudělali, zastavte relaci ladění.

  10. Dále proveďte předchozí změnu řádku 10 a ponechte naši zarážku na řádku 17.

  11. Znovu spusťte ladicí program. Tentokrát, když se dostaneme na zarážku na řádku 17, uvidíme následující hodnoty:

    n [int]: 5
    n1 [int]: 3
    n2 [int]: 5
    sum [int]: 5
    

    Ano! Zdá se, že jsme na to přišli! Výborně, byl to váš úspěšný den ve firmě Fibonacci, Inc.!

  12. Vyberte Continue (Pokračovat), abyste se ujistili, že program vrátí správnou hodnotu.

    5
    The program '[105260] DotNetDebugging.dll' has exited with code 0 (0x0).
    

    A toto správnou hodnotu vrátí.

Zvládli jste to! Ladicím programem pro platformu .NET v editoru Visual Studio Code jste odladili kód, který jste nenapsali.

V další lekci zjistíte, jak pomocí funkcí protokolování a trasování integrovaných v platformě .NET usnadníte ladění kódu, který napíšete.