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 nástroji pro ladění, jako je Visual Studio, abyste našli přesný bod, kdy jste způsobili programátorskou chybu. 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 omyl, 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 můžou překážet v identifikaci problému, i když se přímo díváte na jeho příčinu 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 mohli zpochybnit 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.
Spropitné
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 režimu, který se označuje také jako 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í F5 (nebo zvolením příkazu z nabídky Ladění>Spustit ladění nebo stisknutím tlačítka Spustit ladění na panelu nástrojů Ladění). Pokud dojde k nějaké výjimce, Pomocník pro výjimky ve Visual Studio vás zavede na přesné místo, kde výjimka nastala, 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 zlomu jsou nejdůležitější a základní 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í.
Ve 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 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.
Musíte mít nainstalovanou sadu Visual Studio a nainstalovanou úlohu vývoj desktopových aplikací .NET.
Pokud jste ještě nenainstalovali Visual Studio, přejděte na stránku s možnostmi stažení Visual Studio a nainstalujte ji zdarma.
Pokud potřebujete nainstalovat pracovní zátěž, ale Visual Studio již máte, 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.
Otevřete Visual Studio.
V úvodním okně zvolte Vytvořit nový projekt. Do vyhledávacího pole zadejte konzoly
, vyberte jazyka C# nebojazyka Visual Basic a pak zvolte konzolové aplikacepro .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ě.
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. Pro ladění je důležité pochopit záměr kódu. Tady je formát jednoho řádku ze seznamu, který chceme zobrazit ve výstupu:
galaxy name, vzdálenost, typ galaxie.
Spuštění aplikace
Stiskněte klávesu F5 nebo tlačítko Spustit ladění na panelu nástrojů ladění umístěném nad editorem kódu.
Aplikace se spustí a žádné výjimky nejsou ladicím programem zobrazeny. 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
Když je aplikace stále spuštěná, vložte zarážku.
Ve smyčce
foreach
klikněte pravým tlačítkem myši vedle metodyConsole.WriteLine
pro zobrazení místní nabídky a z fly-out nabídky 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.
Když vidíte problém ve výstupu, začnete ladit tím, že se podíváte na předcházející kód, který určuje výstup v ladicím programu.
Vyberte ikonu RestartApp na panelu nástrojů Ladění (kombinace klávesCtrl + Shift + F5).
Aplikace se pozastaví na bodu 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).
Přejeďte myší nad proměnnou
GalaxyType
napravo, a poté nalevo od ikony klíče rozbaltetheGalaxy.GalaxyType
. Vidíte, žeGalaxyType
obsahuje vlastnostMyGType
a hodnota vlastnosti je nastavena naSpiral
."Spirála" je ve skutečnosti správná hodnota, kterou jste očekávali tisknout do konzoly! Je to dobrý začátek, že máte přístup k hodnotě v tomto kódu během spuštění aplikace. 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.
Ve stejném kódu, zatímco stále ladíte, umístěte kurzor na konec
theGalaxy.GalaxyType
a změňte ho natheGalaxy.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.)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 kupředu (a spustí kód) po jednom příkazu. 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 posunout ladicí program, zobrazí se dialogové okno Hot Reload, které oznamuje, že úpravy nelze zkompilovat.
Zobrazí se dialogové okno Upravit a pokračovat, které indikuje, že úpravy nelze zkompilovat.
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 Restartovat.
Vyberte Upravit v dialogovém okně Přehrání za běhu nebo Upravit a pokračovat. Nyní vidíte chybovou zprávu v okně seznamu chyb . Tato chyba značí, že
'object'
neobsahuje definiciMyGType
.I když nastavíme každou galaxii s objektem typu
GType
(který má vlastnostMyGType
), ladicí program nerozpoznátheGalaxy
objekt jako objekt typuGType
. 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 třídaGType
rozhodně má vlastnostMyGType
, ale něco není v pořádku. Chybová zpráva oobject
se ukáže jako vodítko; pro interpret jazyka se typ jeví jako objekt typuobject
místo objektu typuGType
.Při pohledu na kód související s nastavením typu galaxie zjistíte, že vlastnost
GalaxyType
třídyGalaxy
je určena jakoobject
místoGType
.public object GalaxyType { get; set; }
Změňte předchozí kód následujícím způsobem:
public GType GalaxyType { get; set; }
Vyberte ikonu Restartovat na panelu nástrojů Ladění (Ctrl + Shift + F5) proveďte opětovné kompilování kódu a restartování.
Nyní, když se ladicí program pozastaví na
Console.WriteLine
, můžete najet myší natheGalaxy.GalaxyType.MyGType
a zjistit, že hodnota je správně nastavená.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
Nastavte zarážku na tomto řádku kódu před příkazem
switch
(před příkazemSelect
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.
Vyberte ikonu Restartovat na Panelu nástrojů ladění (Ctrl + Shift + F5) pro restartování.
Ladicí program se pozastaví na řádku kódu, kde nastavíte bod přerušení.
Umístěte kurzor myši nad proměnnou
type
. Zobrazí se hodnotaS
(za kódem znaku). Máte zájem o hodnotuI
, jak víte, je to typ nepravidelné galaxie.Stiskněte F5 a najeďte myší na proměnnou
type
znovu. Tento krok opakujte, dokud neuvidíte hodnotuI
v proměnnétype
.Nyní stiskněte F11 (Ladění>krok do).
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 nadefault
části příkazuswitch
(Else
příkaz v jazyce Visual Basic).Při pohledu na kód se v příkazu
case 'l'
zobrazí překlep. Mělo by to býtcase 'I'
.Vyberte kód pro
case 'l'
a nahraďte hocase 'I'
.Odstraňte zarážku a pak výběrem tlačítka Restartovat 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 použít také 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.
Když zjistíte část 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é 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.)
Spropitné
Používáte ladicí program, abyste našli 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.