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 zázračně odhalit všechny problémy nebo „chyby“ v našem kódu. Ladění znamená spustit váš kód krok za krokem v nástroji pro ladění, jako je Visual Studio, abyste našli přesný bod, kde jste udělali chybu v programu. 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, jak 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 změnu proměnných a zjistit, kdy a jak jsou nesprávné hodnoty přiřazeny.

Prozkoumání předpokladů

Než se pustíte do prošetřování chyby nebo závady, zamyslete se nad předpoklady, které vás vedly k očekávání určitého výsledku. Skryté nebo neznámé předpoklady mohou bránit identifikaci problému, i když se díváte přímo na příčinu problému v debuggeru. Možná máte dlouhý seznam možných předpokladů! Tady je několik otázek, které si můžete položit, abyste zpochybnili 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 nároč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.

    Rada

    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 nástroji, který se označuje také jako režim ladění, ladicí nástroj aktivně monitoruje všechno, co se děje během běhu 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í F5 (nebo Ladění>Spustit ladění menu nebo pomocí tlačítka Spustit laděníIkona s tlačítkem 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 vezme na přesné místo, 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. Body přerušení jsou nejzásadnější funkcí 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 aplikaci Visual Studio můžete rychle nastavit bod přerušení kliknutím na levý okraj vedle řádku kódu. Nebo umístěte kurzor na čáru a stiskněte 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ývoj desktopových aplikací .NET.

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

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

  2. Otevřete Visual Studio.

    V úvodním okně zvolte Vytvořit nový projekt. Do vyhledávacího pole zadejte konzoly, vyberte jazyka C# nebo jazyka Visual Basic a pak zvolte konzolové aplikace pro .NET. Zvolte Další. Jako název projektu zadejte ConsoleApp_FirstApp a vyberte Další.

    Pokud použijete jiný název projektu, budete muset upravit hodnotu oboru názvů tak, aby odpovídala názvu projektu při kopírování ukázkového kódu.

    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 na Tools>Get Tools and Features, která otevře instalační program sady 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íku řešení v pravém podokně.

  3. V 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. Při ladění je důležité porozumět úmyslu kódu. Tady je formát jednoho řádku ze seznamu, který chceme zobrazit ve výstupu:

    název galaxie, vzdálenost, typ galaxie.

Spuštění aplikace

Stiskněte klávesu F5 nebo tlačítko Spustit ladění, na němž se zobrazí ikona tlačítka 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 název třídy, která ukládá 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 bod přerušení.

    Ve smyčce foreach klikněte pravým tlačítkem myši vedle metody Console.WriteLine, zobrazte 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.

    Jakmile uvidíte problém ve výstupu, začnete ladit tím, že se podíváte na předchozí část kódu, která nastavuje výstup v ladicím programu.

  2. Vyberte ikonu Restartovat, která zobrazuje tlačítko RestartApp na panelu nástrojů Ladění, a pak tlačítko na panelu nástrojů Ladění (Ctrl + Shift + F5).

    Aplikace se pozastaví na bodě přerušení, který 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. Vidíte, že GalaxyType obsahuje vlastnost MyGTypea hodnota vlastnosti je nastavena na Spiral.

    snímek obrazovky ladicího programu sady Visual Studio se žlutým řádkem kódu a nabídkou otevřenou pod vlastností Galaxy GalaxyType.

    "Spirála" je ve skutečnosti správná hodnota, kterou jste očekávali tisknout do konzoly! Je dobré, že máte při spuštění aplikace 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. V tom samém kódu, zatímco stále ladíte, umístěte kurzor na konec theGalaxy.GalaxyType a změňte jej na theGalaxy.GalaxyType.MyGType. I když můžete provést úpravy, editor kódu zobrazí chybu (červená vlnovka). (V jazyce Visual Basic se chyba nezobrazuje a tato část kódu funguje.)

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

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

    Když se pokusíte postoupit ladicí program, zobrazí se dialogové okno dynamické načítání, které upozorňuje na to, že úpravy není možné zkompilovat.

    Snímek obrazovky ladicího programu sady Visual Studio se zvýrazněným řádkem kódu červeně a polem se zprávou s vybranou možností Upravit

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

    Snímek obrazovky ladicího programu sady Visual Studio se zvýrazněným řádkem kódu červeně a polem se zprávou s vybranou možností Upravit

    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 RestartovatIkona s tlačítkem Restartovat aplikaci na panelu nástrojů Ladění. tlačítko.

  6. Vyberte Upravit v zprávovém poli Opětovné načítání za provozu nebo Upravit a pokračovat. V okně Seznamu chyb nyní vidíte chybovou zprávu. Tato chyba značí, že 'object' neobsahuje definici MyGType.

    snímek obrazovky ladicího programu sady Visual Studio se zvýrazněným řádkem kódu červeně a oknem Seznam chyb se dvěma uvedenými chybami.

    I když nastavíme každou galaxii s objektem typu GType (který má vlastnost MyGType), ladicí program nerozpozná theGalaxy objekt jako objekt typu GType. Co se děje? Chcete si prohlédnout veškerý kód, který nastavuje typ galaxie. Když to uděláte, vidíte, že třída GType rozhodně má vlastnost MyGType, ale něco není v pořádku. Chybová zpráva o object ukáže jako vodítko; pro jazykový interpret typ se zdá být objektem typu object namísto objektu typu GType.

  7. Při pohledu na kód související s nastavením typu galaxie zjistíte, že vlastnost GalaxyType třídy Galaxy 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 ikonu Restartovat, která zobrazuje tlačítko pro restartování aplikace na panelu nástrojů Ladění. Tlačítko na panelu nástrojů Ladění (Ctrl + Shift + F5) pro překompilování kódu a restartování.

    Nyní, když se ladicí program pozastaví na Console.WriteLine, můžete najet myší na theGalaxy.GalaxyType.MyGTypea ověřit, že je hodnota správně nastavená.

  10. Odeberte zarážku kliknutím na kruh zarážky na levém okraji (nebo klikněte pravým tlačítkem myši a zvolte Zarážku>Odstranit zarážku) a potom pokračujte 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 příkazem switch (před příkazem Select 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. Vyberte ikonu Restartovat, která zobrazuje tlačítko Restartovat aplikaci, na panelu nástrojů Ladění. Poté stiskněte tlačítko na panelu nástrojů Ladění (Ctrl + Shift + F5) pro restartování.

    Debugger se pozastaví na řádku kódu, kde nastavíte bod přerušení.

  13. Najeďte myší na proměnnou type. Zobrazí se hodnota S (za kódem znaku). Máte zájem o hodnotu I, protože víte, že je to nepravidelný typ galaxie.

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

    snímek obrazovky ladicího programu sady Visual Studio se žlutým řádkem kódu a oknem s hodnotou proměnné typu 73 I.

  15. Nyní stiskněte F11 (Ladění>krok do).

  16. Stiskněte F11, dokud se nezastavíte na řádku kódu v příkazu switch 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 nastaví MyGType jako nepravidelný typ galaxie, ale ladicí program tento kód úplně přeskočí a pozastaví se na default části příkazu switch (Else příkaz v jazyce Visual Basic).

    Snímek obrazovky s chybou překlepu

    Při pohledu na kód se v příkazu case 'l' zobrazí překlep. Mělo by to být case 'I'.

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

  18. Odstraňte zarážku, poté klepněte na tlačítko Restartovat a restartujte aplikaci.

    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 krokových příkazů, jako je F10 a F11 najít 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. K protokolování zpráv do okna Výstup můžete také použít trasovací body. 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.

Až najdete část kódu, ve které je problém, použijte ladicí program, abyste ji prozkoumali. 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é mají obsahovat. Pokud zjistíte chybnou hodnotu, zjistěte, kde byla nastavena chybná hodnota (abyste zjistili, kde byla hodnota nastavena, možná budete muset ladicí program restartovat, 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 příkaz switch nastavit typ galaxie na Nepravidelný, ale aplikace kód přeskočila kvůli překlepu.)

Rada

Ladicí program vám pomůže najít chyby. Nástroj pro ladění může najít chyby pro vás 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í jednotkových testů je způsob, jak to udělat.

Další kroky

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