Sdílet prostřednictvím


Ladění pro absolutní začátečníky

Bez selhání kód, který píšeme jako vývojáři softwaru, nedělá vždy to, co jsme očekávali. Někdy to dělá něco úplně jiného! Když dojde k neočekávanému problému, dalším úkolem je zjistit, proč a i když bychom mohli být lákaví jen sledovat náš kód po dobu hodin, je jednodušší a efektivnější používat ladicí nástroj nebo ladicí program.

Ladicí program bohužel není něco, co může magicky odhalit všechny problémy nebo chyby v našem kódu. Ladění znamená spuštění kódu krok za krokem v ladicím nástroji, jako je Visual Studio, a najít přesný bod, kde jste udělali chybu programování. Pak pochopíte, jaké opravy potřebujete udělat v kódu a nástrojích pro ladění, často vám umožní provádět dočasné změny, abyste mohli program dál spouštět.

Efektivní použití ladicího programu je také dovednost, která potřebuje čas a praxi se učit, ale v konečném důsledku je základním úkolem každého vývojáře softwaru. V tomto článku představíme základní principy ladění a nabídneme tipy, které vám pomůžou začít.

Objasnění problému tím, že se ptáte na správné otázky

Pomůže vám to objasnit problém, na který jste narazili, než se ho pokusíte opravit. Očekáváme, že jste už narazili na problém ve vašem kódu, jinak byste se tady nepokoušeli zjistit, jak ho ladit. Než tedy začnete s laděním, ujistěte se, že jste identifikovali problém, který se pokoušíte vyřešit:

  • Co jste očekávali, že váš kód udělá?

  • Co se místo toho stalo?

    Pokud při spuštění aplikace narazíte na chybu (výjimku), může to být dobrá věc! Výjimkou je neočekávaná událost, ke které došlo při spuštění kódu, obvykle k nějaké chybě. Nástroj pro ladění vás může dostat na přesné místo v kódu, kde došlo k výjimce, a může vám pomoct prozkoumat možné opravy.

    Pokud se stalo něco jiného, jaký je příznak problému? Už máte podezření, kde k tomuto problému došlo ve vašem kódu? Pokud například váš kód zobrazí nějaký text, ale text je nesprávný, víte, že data jsou chybná nebo kód, který nastavil zobrazovaný text, má nějaký druh chyby. Krokováním kódu v ladicím programu můžete prozkoumat každou a každou změnu proměnných a zjistit, kdy a jak jsou přiřazeny nesprávné hodnoty.

Prozkoumání předpokladů

Než prošetříte chybu nebo chybu, představte si předpoklady, které jste očekávali určitý výsledek. Skryté nebo neznámé předpoklady se můžou dostat způsobem identifikace problému, i když se díváte na příčinu problému v ladicím programu. Možná máte dlouhý seznam možných předpokladů! Tady je několik otázek, na které se můžete zeptat, abyste se mohli ptát na své předpoklady.

  • Používáte správné rozhraní API (to znamená správný objekt, funkci, metodu nebo vlastnost)? Rozhraní API, které používáte, nemusí dělat to, co si myslíte. (Po prozkoumání volání rozhraní API v ladicím programu může oprava vyžadovat cestu do dokumentace, která vám pomůže identifikovat správné rozhraní API.)

  • Používáte rozhraní API správně? Možná jste použili správné rozhraní API, ale nepoužívali ho správným způsobem.

  • Obsahuje váš kód nějaké překlepy? Některé překlepy, například jednoduché chybně napsané názvy proměnných, můžou být obtížně vidět, zejména při práci s jazyky, které nevyžadují deklarování proměnných před použitím.

  • Provedli jste v kódu změnu a předpokládáte, že nesouvisí s problémem, který vidíte?

  • Očekávali jste, že objekt nebo proměnná obsahují určitou hodnotu (nebo určitý typ hodnoty), která se liší od toho, co se skutečně stalo?

  • Znáte záměr kódu? Ladění kódu někoho jiného je často obtížnější. Pokud se nejedná o váš kód, je možné, že budete muset věnovat čas tomu, co kód dělá, abyste ho mohli efektivně ladit.

    Tip

    Při psaní kódu začněte malými a začněte kódem, který funguje! (Tady je užitečný dobrý vzorový kód.) Někdy je jednodušší opravit velkou nebo složitou sadu kódu tím, že začnete s malou částí kódu, která ukazuje základní úlohu, kterou se pokoušíte dosáhnout. Pak můžete upravit nebo přidat kód přírůstkově a v každém okamžiku testovat chyby.

Dotazováním předpokladů můžete zkrátit dobu potřebnou k nalezení problému v kódu. Můžete také zkrátit dobu potřebnou k vyřešení problému.

Projděte si kód v režimu ladění a zjistěte, kde k problému došlo.

Při normálním spuštění aplikace se zobrazí chyby a nesprávné výsledky až po spuštění kódu. Program se také může neočekávaně ukončit, aniž byste řekli, proč.

Když spustíte aplikaci v ladicím programu, kterému se říká také režim ladění, ladicí program aktivně monitoruje vše, co se děje při spuštění programu. Umožňuje také pozastavit aplikaci v libovolném okamžiku, abyste prozkoumali její stav, a pak krokujte řádkem kódu po řádku a sledujte všechny podrobnosti, jak se to stane.

V sadě Visual Studio přejdete do režimu ladění pomocí klávesy F5 (nebo >příkazu nabídky Spustit ladění nebo tlačítkaIcon showing Start Debugging button.Spustit ladění na panelu nástrojů Ladění). Pokud dojde k nějakým výjimkám, pomocník pro výjimky sady Visual Studio vás přesná místa, kde došlo k výjimce, a poskytne další užitečné informace. Další informace o zpracování výjimek v kódu naleznete v tématu Techniky ladění a nástroje.

Pokud jste nedostali výjimku, pravděpodobně máte dobrou představu o tom, kde hledat problém v kódu. V tomto kroku použijete zarážky s ladicím programem, abyste se mohli důkladněji podívat na kód. Zarážky jsou nejzákladnějším rysem spolehlivého ladění. Zarážka označuje, kde má Visual Studio pozastavit spuštěný kód, abyste se mohli podívat na hodnoty proměnných nebo na chování paměti, pořadí, ve kterém se kód spouští.

V sadě Visual Studio můžete rychle nastavit zarážku kliknutím na levý okraj vedle řádku kódu. Nebo umístěte kurzor na čáru a stiskněte klávesu F9.

Abychom vám pomohli tyto koncepty ilustrovat, projdeme si ukázkový kód, který už obsahuje několik chyb. Používáme jazyk C#, ale funkce ladění platí pro Visual Basic, C++, JavaScript, Python a další podporované jazyky. K dispozici je také ukázkový kód pro Visual Basic, ale snímky obrazovky jsou v jazyce C#.

Vytvoření ukázkové aplikace (s některými chybami)

Dále vytvoříte aplikaci, která obsahuje několik chyb.

  1. Musíte mít nainstalovanou sadu Visual Studio a nainstalovanou úlohu vývoje desktopových aplikací .NET.

    Pokud jste visual Studio ještě nenainstalovali, přejděte na stránku pro stažení sady Visual Studio a nainstalujte ji zdarma.

    Pokud potřebujete nainstalovat úlohu, ale sadu Visual Studio už máte, vyberte Nástroje Získat nástroje>a funkce. Spustí se instalační program pro Visual Studio. Zvolte úlohu vývoje desktopových aplikací .NET a pak zvolte Upravit.

  2. Otevřete sadu Visual Studio.

    V úvodním okně zvolte Vytvořit nový projekt. Do vyhledávacího pole zadejte konzolu , vyberte jazyk C# nebo Visual Basic a pak zvolte Konzolová aplikace pro .NET. Zvolte Další. Zadejte název projektu, například ConsoleApp_FirstApp , a vyberte Další.

    Zvolte buď doporučenou cílovou architekturu, nebo .NET 8, a pak zvolte Vytvořit.

    Pokud šablonu projektu konzolové aplikace pro .NET nevidíte, přejděte do části Nástroje>Získat nástroje a funkce, která otevře Instalační program pro Visual Studio. Zvolte úlohu vývoje desktopových aplikací .NET a pak zvolte Upravit.

    Visual Studio vytvoří projekt konzoly, který se zobrazí v Průzkumník řešení v pravém podokně.

  3. V souboru Program.cs (nebo Program.vb) nahraďte veškerý výchozí kód následujícím kódem. (Nejprve vyberte správnou kartu jazyka, jazyk C# nebo Visual Basic.)

    using System;
    using System.Collections.Generic;
    
    namespace ConsoleApp_FirstApp
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Welcome to Galaxy News!");
                IterateThroughList();
                Console.ReadKey();
            }
    
            private static void IterateThroughList()
            {
                var theGalaxies = new List<Galaxy>
            {
                new Galaxy() { Name="Tadpole", MegaLightYears=400, GalaxyType=new GType('S')},
                new Galaxy() { Name="Pinwheel", MegaLightYears=25, GalaxyType=new GType('S')},
                new Galaxy() { Name="Cartwheel", MegaLightYears=500, GalaxyType=new GType('L')},
                new Galaxy() { Name="Small Magellanic Cloud", MegaLightYears=.2, GalaxyType=new GType('I')},
                new Galaxy() { Name="Andromeda", MegaLightYears=3, GalaxyType=new GType('S')},
                new Galaxy() { Name="Maffei 1", MegaLightYears=11, GalaxyType=new GType('E')}
            };
    
                foreach (Galaxy theGalaxy in theGalaxies)
                {
                    Console.WriteLine(theGalaxy.Name + "  " + theGalaxy.MegaLightYears + ",  " + theGalaxy.GalaxyType);
                }
    
                // Expected Output:
                //  Tadpole  400,  Spiral
                //  Pinwheel  25,  Spiral
                //  Cartwheel, 500,  Lenticular
                //  Small Magellanic Cloud .2,  Irregular
                //  Andromeda  3,  Spiral
                //  Maffei 1,  11,  Elliptical
            }
        }
    
        public class Galaxy
        {
            public string Name { get; set; }
    
            public double MegaLightYears { get; set; }
            public object GalaxyType { get; set; }
    
        }
    
        public class GType
        {
            public GType(char type)
            {
                switch(type)
                {
                    case 'S':
                        MyGType = Type.Spiral;
                        break;
                    case 'E':
                        MyGType = Type.Elliptical;
                        break;
                    case 'l':
                        MyGType = Type.Irregular;
                        break;
                    case 'L':
                        MyGType = Type.Lenticular;
                        break;
                    default:
                        break;
                }
            }
            public object MyGType { get; set; }
            private enum Type { Spiral, Elliptical, Irregular, Lenticular}
        }
    }
    

    Naším záměrem tohoto kódu je zobrazit název galaxie, vzdálenost k galaxii a typ galaxie všechny v seznamu. K ladění je důležité porozumět záměru kódu. Tady je formát jednoho řádku ze seznamu, který chceme zobrazit ve výstupu:

    galaxy name, distance, galaxy type.

Spustit aplikaci

Stiskněte klávesu F5 nebo tlačítko Icon showing Start Debugging button.Spustit ladění na panelu nástrojů Ladění umístěném nad editorem kódu.

Aplikace se spustí a ladicí program nám nezobrazuje žádné výjimky. Výstup, který se zobrazí v okně konzoly, ale není to, co očekáváte. Tady je očekávaný výstup:

Tadpole  400,  Spiral
Pinwheel  25,  Spiral
Cartwheel, 500,  Lenticular
Small Magellanic Cloud .2,  Irregular
Andromeda  3,  Spiral
Maffei 1,  Elliptical

Ale místo toho se zobrazí tento výstup:

Tadpole  400,  ConsoleApp_FirstApp.GType
Pinwheel  25,  ConsoleApp_FirstApp.GType
Cartwheel, 500,  ConsoleApp_FirstApp.GType
Small Magellanic Cloud .2,  ConsoleApp_FirstApp.GType
Andromeda  3,  ConsoleApp_FirstApp.GType
Maffei 1, 11,  ConsoleApp_FirstApp.GType

Když se podíváme na výstup a náš kód, víme, že GType je to název třídy, která uchovává typ galaxie. Snažíme se ukázat skutečný typ galaxie (například "Spirála"), ne název třídy!

Ladění aplikace

  1. Když je aplikace stále spuštěná, vložte zarážku.

    Kliknutím pravým tlačítkem myši vedle Console.WriteLine metody získáte místní nabídku a v rozevírací nabídce vyberte Zarážku Vložit zarážku>.

    foreach (Galaxy theGalaxy in theGalaxies)
    {
        Console.WriteLine(theGalaxy.Name + "  " + theGalaxy.MegaLightYears + ",  " + theGalaxy.GalaxyType);
    }
    

    Když nastavíte zarážku, zobrazí se na levém okraji červená tečka.

    Jak vidíte problém ve výstupu, spustíte ladění tím, že se podíváte na předchozí kód, který nastaví výstup v ladicím programu.

  2. Na panelu nástrojů Ladění vyberte tlačítko RestartovatIcon showing RestartApp button in Debug toolbar. (Ctrl + Shift + F5).

    Aplikace se pozastaví na zarážce, kterou jste nastavili. Žluté zvýraznění označuje, kde je ladicí program pozastavený (žlutý řádek kódu ještě nebyl proveden).

  3. Najeďte myší na proměnnou GalaxyType vpravo a potom nalevo od ikony klíče rozbalte theGalaxy.GalaxyType. Uvidíte, že GalaxyType obsahuje vlastnost MyGTypea hodnota vlastnosti je nastavena na Spiral.

    Screenshot of the Visual Studio Debugger with a line of code in yellow and a menu open below the Galaxy GalaxyType property.

    "Spirála" je ve skutečnosti správná hodnota, kterou jste očekávali tisknout do konzoly! Proto je dobré začít, abyste při spuštění aplikace měli přístup k hodnotě v tomto kódu. V tomto scénáři používáme nesprávné rozhraní API. Pojďme se podívat, jestli to můžete opravit při spouštění kódu v ladicím programu.

  4. Ve stejném kódu, zatímco stále ladění, umístěte kurzor na konec a změňte ho theGalaxy.GalaxyType na theGalaxy.GalaxyType.MyGType. I když můžete provést změnu, editor kódu zobrazí chybu, která indikuje, že tento kód nemůže zkompilovat. (V jazyce Visual Basic se chyba nezobrazuje a tato část kódu funguje.)

  5. Stisknutím klávesy F11 (krok pro ladění>nebo tlačítko Krok do na panelu nástrojů Ladění) spusťte aktuální řádek kódu.

    F11 provede ladicí program (a spustí kód) vždy jeden příkaz. F10 (Krok přes) je podobný příkaz a oba jsou užitečné při učení, jak používat ladicí program.

    Zobrazí se dialogové okno Upravit a pokračovat, které indikuje, že úpravy nelze zkompilovat.

    Screenshot of the Visual Studio Debugger with a line of code highlighted in red and a message box with the Edit option selected.

    Poznámka:

    Pro ladění ukázkového kódu jazyka Visual Basic přeskočte několik dalších kroků, dokud nebudete vyzváni, abyste klikli na tlačítko RestartovatIcon showing Restart app button in Debug toolbar..

  6. Vyberte Upravit v okně Upravit a pokračovat ve zprávě. V okně Seznam chyb se teď zobrazí chybová zpráva. Chyba značí, že 'object' neobsahuje definici pro MyGType.

    Screenshot of the Visual Studio Debugger with a line of code highlighted in red and an Error List window with two errors listed.

    I když jsme nastavili každou galaxii s objektem typu GType (který má MyGType vlastnost), ladicí program nerozpozná theGalaxy objekt jako objekt typu GType. Co se děje? Chcete se podívat na jakýkoli kód, který nastaví typ galaxie. Když to uděláte, vidíte, že GType třída rozhodně má vlastnost MyGType, ale něco není v pořádku. Chybová zpráva o object tom, že je vodítkem; pro interpret jazyka se zdá, že typ je objekt object typu místo objektu typu GType.

  7. Při prohlížení kódu souvisejícího s nastavením typu galaxie zjistíte, že GalaxyType vlastnost Galaxy třídy je určena jako object místo GType.

    public object GalaxyType { get; set; }
    
  8. Změňte předchozí kód následujícím způsobem:

    public GType GalaxyType { get; set; }
    
  9. Vyberte tlačítko RestartovatIcon showing Restart app button in Debug toolbar. na panelu nástrojů ladění (Ctrl + Shift + F5) a znovu zkompilujte kód a restartujte ho.

    Když se ladicí program pozastaví Console.WriteLine, můžete najet myší theGalaxy.GalaxyType.MyGTypea zjistit, že je hodnota správně nastavená.

  10. Odeberte zarážku tak, že kliknete na kruh zarážky na levém okraji (nebo na ně kliknete pravým tlačítkem myši a zvolíte Zarážku>Odstranit zarážku) a pak budete pokračovat stisknutím klávesy F5.

    Aplikace se spustí a zobrazí výstup. Vypadá to dobře, ale všimnete si jedné věci. Očekávali jste, že malá magellanicová cloudová galaxie se ve výstupu konzoly zobrazí jako nepravidelná galaxie, ale vůbec nezobrazuje žádný typ galaxie.

    Tadpole  400,  Spiral
    Pinwheel  25,  Spiral
    Cartwheel, 500,  Lenticular
    Small Magellanic Cloud .2,
    Andromeda  3,  Spiral
    Maffei 1,  Elliptical
    
  11. Nastavte zarážku na tomto řádku kódu před switch příkazem (před Select příkazem v jazyce Visual Basic).

    public GType(char type)
    

    Tento kód je tam, kde je typ galaxie nastaven, takže se na něj chceme podívat podrobněji.

  12. Chcete-li restartovat, vyberte tlačítko RestartovatIcon showing Restart app button in Debug toolbar. na panelu nástrojů ladění (Ctrl + Shift + F5).

    Ladicí program se pozastaví na řádku kódu, kde nastavíte zarážku.

  13. Najeďte myší na proměnnou type . Zobrazí se hodnota S (za kódem znaku). Zajímá vás hodnota I, jak víte, že je nepravidelný typ galaxie.

  14. Stiskněte klávesu F5 a najeďte myší na proměnnou type znovu. Tento krok opakujte, dokud neuvidíte hodnotu I v type proměnné.

    Screenshot of the Visual Studio Debugger with a line of code in yellow and a window with the type variable value of 73 I.

  15. Teď stiskněte klávesu F11 (krok pro ladění>).

  16. Opakovaně stiskněte klávesu F11, dokud se nezastavíte na řádku kódu v switch příkazu pro hodnotu "I" (Select příkaz pro Visual Basic). Tady vidíte jasný problém vyplývající z překlepu. Očekávali jste, že kód přejde na místo, kde se nastaví MyGType jako nepravidelný typ galaxie, ale ladicí program místo toho tento kód zcela přeskočí a pozastaví se v default části switch příkazu (Else příkaz v jazyce Visual Basic).

    Screenshot showing the typo error.

    Při pohledu na kód se v case 'l' příkazu zobrazí překlep. Měla by mít hodnotu case 'I'.

  17. Vyberte kód pro case 'l' a nahraďte ho znakem case 'I'.

  18. Odeberte zarážku a pak výběrem tlačítka Restartovat aplikaci restartujte.

    Chyby jsou opraveny a uvidíte výstup, který očekáváte.

    Stisknutím libovolné klávesy aplikaci dokončete.

Shrnutí

Když se zobrazí problém, pomocí ladicího programu a příkazů kroků, jako je F10 a F11 , vyhledejte oblast kódu s problémem.

Poznámka:

Pokud je obtížné identifikovat oblast kódu, ve které k problému dochází, nastavte zarážku v kódu, který se spustí před výskytem problému, a pak použijte příkazy kroků, dokud neuvidíte manifest problému. Pomocí trasovacích bodů můžete také protokolovat zprávy do okna Výstup. Když se podíváte na protokolované zprávy (a zjistíte, které zprávy ještě nebyly zaprotokolovány!), můžete často izolovat oblast kódu s problémem. Možná budete muset tento proces několikrát zopakovat, abyste ho zúžili.

Když zjistíte oblast kódu s problémem, použijte ladicí program k prozkoumání. Pokud chcete zjistit příčinu problému, zkontrolujte kód problému při spuštění aplikace v ladicím programu:

  • Zkontrolujte proměnné a zkontrolujte, jestli obsahují typ hodnot, které by měly obsahovat. Pokud zjistíte chybnou hodnotu, zjistěte, kde byla nastavena chybná hodnota (pokud chcete zjistit, kde byla hodnota nastavena, možná budete muset buď restartovat ladicí program, podívat se na zásobník volání nebo obojí).

  • Zkontrolujte, jestli aplikace spouští očekávaný kód. (Například v ukázkové aplikaci jsme očekávali kód pro switch příkaz nastavit typ galaxie na Nepravidelný, ale aplikace kód přeskočila kvůli překlepu.)

Tip

Ladicí program vám pomůže najít chyby. Nástroj pro ladění může najít chyby pouze v případě, že zná záměr vašeho kódu. Nástroj může znát záměr vašeho kódu pouze v případě, že tento záměr vyjadřujete vy, vývojář. Psaní testů jednotek je způsob, jakým to uděláte.

Další kroky

V tomto článku jste se naučili několik obecných konceptů ladění. V dalším kroku se můžete dozvědět více o ladicím programu.