Delen via


Debuggen voor absolute beginners

Zonder uitzondering doet de code die we als softwareontwikkelaars schrijven niet altijd wat we verwachten. Soms doet het iets heel anders! Wanneer het onverwachte gebeurt, is de volgende taak om erachter te komen waarom, en hoewel we misschien geneigd zijn om urenlang naar onze code te staren, is het eenvoudiger en efficiënter om een foutopsporingsprogramma of foutopsporingsprogramma te gebruiken.

Een foutopsporingsprogramma is helaas niet iets dat magisch alle problemen of 'bugs' in onze code kan onthullen. Foutopsporing betekent dat u uw code stap voor stap uitvoert in een hulpprogramma voor foutopsporing, zoals Visual Studio, om het exacte punt te vinden waar u een programmeerfout hebt gemaakt. Vervolgens begrijpt u welke correcties u moet aanbrengen in uw code en hulpprogramma's voor foutopsporing, kunt u vaak tijdelijke wijzigingen aanbrengen, zodat u het programma kunt blijven uitvoeren.

Het gebruik van een foutopsporingsprogramma is ook een vaardigheid die tijd en oefening kost om te leren, maar uiteindelijk een fundamentele taak is voor elke softwareontwikkelaar. In dit artikel introduceren we de belangrijkste principes van foutopsporing en geven we tips om u op weg te helpen.

Verhelder het probleem door uzelf de juiste vragen te stellen

Het helpt om het probleem te verduidelijken dat u tegenkomt voordat u het probeert op te lossen. We verwachten dat er al een probleem is opgetreden in uw code, anders zou u hier niet proberen te achterhalen hoe u fouten kunt opsporen. Voordat u begint met foutopsporing, moet u er dus voor zorgen dat u het probleem hebt geïdentificeerd dat u probeert op te lossen:

  • Wat verwachtte u van uw code?

  • Wat is er gebeurd?

    Als er een fout (uitzondering) optreedt tijdens het uitvoeren van uw app, kan dit een goede zaak zijn. Een uitzondering is een onverwachte gebeurtenis die optreedt bij het uitvoeren van code, meestal een fout van een bepaald type. Met een hulpprogramma voor foutopsporing kunt u naar de exacte plaats in uw code gaan waar de uitzondering is opgetreden en kunt u mogelijke oplossingen onderzoeken.

    Als er iets anders is gebeurd, wat is het symptoom van het probleem? Vermoedt u al waar dit probleem is opgetreden in uw code? Als uw code bijvoorbeeld tekst weergeeft, maar de tekst onjuist is, weet u dat uw gegevens slecht zijn of dat de code waarmee de weergavetekst is ingesteld, een fout heeft. Door de code in een foutopsporingsprogramma te doorlopen, kunt u elke wijziging in uw variabelen bekijken om precies te ontdekken wanneer en hoe onjuiste waarden worden toegewezen.

Uw veronderstellingen onderzoeken

Voordat je een bug of een fout gaat onderzoeken, denk aan de veronderstellingen die je deden verwachten een bepaald resultaat te zien. Verborgen of onbekende aannames kunnen het moeilijk maken een probleem te identificeren, zelfs wanneer u direct naar de oorzaak ervan in een debugger kijkt. Misschien hebt u een lange lijst met mogelijke veronderstellingen! Hier volgen enkele vragen om uzelf te vragen om uw veronderstellingen uit te dagen.

  • Gebruikt u de juiste API (dat wil zeggen het juiste object, de juiste functie, methode of eigenschap)? Een API die u gebruikt, doet mogelijk niet wat u ervan vindt. (Nadat u de API-aanroep in het foutopsporingsprogramma hebt bekeken, kan het oplossen ervan een trip naar de documentatie vereisen om de juiste API te identificeren.)

  • Gebruikt u een API correct? Misschien hebt u de juiste API gebruikt, maar deze niet op de juiste manier gebruikt.

  • Bevat uw code typfouten? Sommige typefouten, zoals een eenvoudige spelfout in een variabelenaam, kunnen moeilijk te zien zijn, vooral bij het werken met talen waarvoor geen variabelen hoeven te worden gedeclareerd voordat ze worden gebruikt.

  • Hebt u een wijziging aangebracht in uw code en ervan uitgegaan dat deze niet is gerelateerd aan het probleem dat u ziet?

  • Had u verwacht dat een object of variabele een bepaalde waarde (of een bepaald type waarde) bevat die verschilt van wat er echt is gebeurd?

  • Weet u wat de bedoeling van de code is? Het is vaak moeilijker om fouten op te sporen in de code van iemand anders. Als het niet uw code is, is het mogelijk dat u tijd moet besteden aan het leren wat de code doet voordat u effectief fouten kunt opsporen.

    Fooi

    Begin bij het schrijven van code klein en begin met code die werkt. (Goede voorbeeldcode is hier nuttig.) Soms is het eenvoudiger om een grote of gecompliceerde set code op te lossen door te beginnen met een klein stukje code dat de kerntaak laat zien die u probeert te bereiken. Vervolgens kunt u code incrementeel wijzigen of toevoegen, zodat u op elk punt op fouten kunt testen.

Door uw veronderstellingen te ondervragen, kunt u de tijd beperken die nodig is om een probleem in uw code te vinden. U kunt ook de tijd verminderen die nodig is om een probleem op te lossen.

Doorloop uw code in de foutopsporingsmodus om te achterhalen waar het probleem is opgetreden

Wanneer u normaal gesproken een app uitvoert, ziet u fouten en onjuiste resultaten pas nadat de code is uitgevoerd. Een programma kan ook onverwacht worden beëindigd zonder u te vertellen waarom.

Wanneer u een app uitvoert in een foutopsporingsprogramma, ook wel foutopsporingsmodusgenoemd, controleert het foutopsporingsprogramma alles wat er gebeurt terwijl het programma wordt uitgevoerd. U kunt de app ook op elk gewenst moment onderbreken om de status ervan te onderzoeken en vervolgens de coderegel per regel doorlopen om alle details te bekijken terwijl deze zich voordoet.

In Visual Studio gaat u de foutopsporingsmodus in met behulp van F5 (of de Foutopsporing>Debugging starten menuopdracht of de knop Foutopsporing starten knop pictogram dat de knop Foutopsporing starten aangeeft. op de werkbalk Foutopsporing). Als er uitzonderingen optreden, gaat u met de Uitzonderingshulpfunctie van Visual Studio naar het exacte punt waar de uitzondering is opgetreden en vindt u andere nuttige informatie. Zie Technieken en hulpprogramma's voor foutopsporingvoor meer informatie over het afhandelen van uitzonderingen in uw code.

Als u geen uitzondering krijgt, hebt u waarschijnlijk een goed idee waar u naar het probleem in uw code kunt zoeken. In deze stap gebruikt u onderbrekingspunten met het foutopsporingsprogramma om uzelf een kans te geven om uw code zorgvuldiger te onderzoeken. Onderbrekingspunten zijn de meest elementaire en essentiële functie van betrouwbare foutopsporing. Een onderbrekingspunt geeft aan waar Visual Studio de actieve code moet onderbreken, zodat u de waarden van variabelen, of het gedrag van het geheugen, kunt bekijken in de volgorde waarin code wordt uitgevoerd.

In Visual Studio kunt u snel een onderbrekingspunt instellen door in de linkermarge naast een regel code te klikken. Of plaats de cursor op een lijn en druk op F9.

Om deze concepten te illustreren, nemen we u door een aantal voorbeeldcode die al verschillende bugs bevat. We gebruiken C#, maar de foutopsporingsfuncties zijn van toepassing op Visual Basic, C++, JavaScript, Python en andere ondersteunde talen. Er is ook voorbeeldcode voor Visual Basic opgegeven, maar schermopnamen bevinden zich in C#.

Een voorbeeld-app maken (met een aantal bugs)

Vervolgens maakt u een toepassing met een aantal bugs.

  1. Je moet Visual Studio hebben geïnstalleerd en de .NET-desktopontwikkeling-workload geïnstalleerd hebben.

    Als u Visual Studio nog niet hebt geïnstalleerd, gaat u naar de Visual Studio-downloadpagina pagina om deze gratis te installeren.

    Als u de workload wilt installeren maar Visual Studio al hebt, selecteert u Tools>Hulpprogramma's en onderdelen ophalen. Het installatieprogramma van Visual Studio wordt gestart. Kies de .NET-desktopontwikkelingswerklast en selecteer vervolgens Wijzigen.

  2. Open Visual Studio.

    Kies in het startvenster Een nieuw project maken. Typ console in het zoekvak, selecteer C#- of Visual Basic- als taal en kies vervolgens Console-app voor .NET. Kies Volgende. Typ ConsoleApp_FirstApp als projectnaam en selecteer Volgende.

    Als u een andere projectnaam gebruikt, moet u de waarde van de naamruimte wijzigen zodat deze overeenkomt met de projectnaam wanneer u de voorbeeldcode kopieert.

    Kies het aanbevolen doelframework of .NET 8 en selecteer vervolgens Aanmaken.

    Als u de Console-app projectsjabloon voor .NET niet ziet, gaat u naar Tools>Hulpprogramma's en onderdelen ophalen, waarmee het installatieprogramma van Visual Studio wordt geopend. Kies de .NET-desktopontwikkelingswerklast en selecteer vervolgens Wijzigen.

    Visual Studio maakt het consoleproject, dat wordt weergegeven in Solution Explorer in het rechterdeelvenster.

  3. Vervang in Program.cs (of Program.vb) alle standaardcode door de volgende code. (Selecteer eerst het juiste taaltabblad, C# of 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}
        }
    }
    

    Onze bedoeling voor deze code is om de galaxynaam, de afstand tot het melkwegstelsel en het galaxytype allemaal in een lijst weer te geven. Als u fouten wilt opsporen, is het belangrijk dat u de intentie van de code begrijpt. Dit is de indeling voor één regel in de lijst die we in de uitvoer willen weergeven:

    sterrenstelsel naam, afstand, sterrenstelseltype.

De app uitvoeren

Druk op F5 of op de knop Start Debugging, aangeduid met het pictogram voor de knop Foutopsporing starten, in de foutopsporingswerkbalk boven de code-editor.

De app wordt gestart en er worden geen uitzonderingen weergegeven door het foutopsporingsprogramma. De uitvoer die u in het consolevenster ziet, is echter niet wat u verwacht. Dit is de verwachte uitvoer:

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

Maar in plaats daarvan ziet u deze uitvoer:

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

Als we kijken naar de uitvoer en onze code, weten we dat GType de naam is van de klasse waarin het galaxy-type wordt opgeslagen. We proberen het werkelijke galaxytype (zoals 'Spiraal'), niet de klassenaam weer te geven.

Fouten opsporen in de app

  1. Wanneer de app nog steeds wordt uitgevoerd, voegt u een onderbrekingspunt in.

    Klik in de foreach lus met de rechtermuisknop naast de methode Console.WriteLine om het contextmenu op te halen en selecteer Onderbrekingspunt invoegen>Onderbrekingspunt invoegen in het vervolgmenu.

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

    Wanneer u het onderbrekingspunt instelt, wordt er een rode stip weergegeven in de linkermarge.

    Als u een probleem in de uitvoer ziet, begint u met foutopsporing door te kijken naar de voorgaande code waarmee de uitvoer in het foutopsporingsprogramma wordt ingesteld.

  2. Selecteer het pictogram Opnieuw opstartendat de knop RestartApp toont in de foutopsporingswerkbalk. knop in de foutopsporingswerkbalk (Ctrl + Shift + F5).

    De app wordt gepauzeerd bij het onderbrekingspunt dat u hebt ingesteld. De gele markering geeft aan waar het foutopsporingsprogramma is onderbroken (de gele coderegel is nog niet uitgevoerd).

  3. Beweeg de muisaanwijzer over de variabele GalaxyType aan de rechterkant en vouw vervolgens links van het sleutelpictogram theGalaxy.GalaxyTypeuit. U ziet dat GalaxyType een eigenschap bevat MyGTypeen dat de eigenschapswaarde is ingesteld op Spiral.

    Schermopname van het Visual Studio Debugger met een coderegel in geel en een menu geopend onder de eigenschap Galaxy GalaxyType.

    'Spiraal' is eigenlijk de juiste waarde die je verwachtte te printen op de console! Het is dus een goed begin dat u toegang hebt tot de waarde in deze code tijdens het uitvoeren van de app. In dit scenario gebruiken we de onjuiste API. Laten we eens kijken of u dit kunt oplossen tijdens het uitvoeren van code in het foutopsporingsprogramma.

  4. Terwijl u aan het debuggen bent, plaatst u de cursor aan het einde van theGalaxy.GalaxyType en wijzigt u deze in theGalaxy.GalaxyType.MyGTypein dezelfde code. Hoewel u de bewerking kunt doorvoeren, ziet u in de code-editor een fout (rode golvende lijn). (In Visual Basic wordt de fout niet vertoond en werkt deze code-sectie.)

  5. Druk op F11 (Fouten opsporen>Stap in of de knop Stap in in de werkbalk Foutopsporing) om de huidige coderegel uit te voeren.

    F11 voert de debugger één instructie tegelijk uit (en voert code uit). F10 (Step Over) is een vergelijkbare opdracht en beide zijn handig bij het gebruik van het foutopsporingsprogramma.

    Als u probeert de debugger verder te zetten, verschijnt het dialoogvenster Hot Reload, dat aangeeft dat bewerkingen niet kunnen worden gecompileerd.

    Schermopname van het Visual Studio Debugger met een coderegel rood gemarkeerd en een berichtvak met de optie Bewerken geselecteerd.

    Het dialoogvenster Bewerken en Doorgaan wordt weergegeven, waarmee wordt aangegeven dat bewerkingen niet kunnen worden gecompileerd.

    Schermopname van het Visual Studio Debugger met een coderegel rood gemarkeerd en een berichtvak met de optie Bewerken geselecteerd.

    Notitie

    Voor foutopsporing van de Visual Basic-voorbeeldcode slaat u de volgende stappen over totdat u wordt gevraagd op het pictogram Opnieuw opstartente klikken met de knop App opnieuw opstarten in de werkbalk Foutopsporing. knop.

  6. Selecteer bewerken in het berichtvak Dynamisch opnieuw laden of Bewerken en Doorgaan. U ziet nu een foutbericht in het venster Foutenlijst. De fout geeft aan dat de 'object' geen definitie voor MyGTypebevat.

    Schermopname van het Visual Studio Debugger met een coderegel rood gemarkeerd en een venster foutenlijst met twee fouten.

    Hoewel we elke galaxy instellen met een object van het type GType (die de eigenschap MyGType heeft), herkent het foutopsporingsprogramma het theGalaxy object niet als een object van het type GType. Wat gebeurt er? U wilt alle code bekijken waarmee het galaxy-type wordt ingesteld. Als u dit doet, ziet u dat de GType klasse zeker een eigenschap van MyGTypeheeft, maar dat er iets niet klopt. Het foutbericht over object blijkt de aanwijzing te zijn; voor de taal-interpreter lijkt het type een object van het type object te zijn in plaats van een object van het type GType.

  7. Tijdens het doorzoeken van de code met betrekking tot het instellen van het galaxietype, ontdekt u dat de eigenschap GalaxyType van de klasse Galaxy is opgegeven als object in plaats van GType.

    public object GalaxyType { get; set; }
    
  8. Wijzig de voorgaande code als volgt:

    public GType GalaxyType { get; set; }
    
  9. Selecteer het pictogram Opnieuw opstartendat de knop App opnieuw opstarten weergeeft in de foutopsporingswerkbalk. knop in de foutopsporingswerkbalk (Ctrl + Shift + F5) om de code opnieuw te compileren en opnieuw op te starten.

    Wanneer het foutopsporingsprogramma wordt onderbroken op Console.WriteLine, kunt u de muisaanwijzer over theGalaxy.GalaxyType.MyGTypebewegen en zien dat de waarde juist is ingesteld.

  10. Verwijder het onderbrekingspunt door te klikken op de onderbrekingspuntcirkel in de linkermarge (of klik met de rechtermuisknop en kies onderbrekingspunt>Onderbrekingspunt verwijderen) en druk vervolgens op F5 om door te gaan.

    De app draait en de uitvoer wordt weergegeven. Het ziet er goed uit, maar je ziet één ding. U had verwacht dat de Small Magellanic Cloud als een onregelmatig sterrenstelsel in de console-uitvoer zou verschijnen, maar het toont helemaal geen type sterrenstelsel.

    Tadpole  400,  Spiral
    Pinwheel  25,  Spiral
    Cartwheel, 500,  Lenticular
    Small Magellanic Cloud .2,
    Andromeda  3,  Spiral
    Maffei 1,  Elliptical
    
  11. Stel een onderbrekingspunt in op deze regel code vóór de switch instructie (vóór de Select-instructie in Visual Basic).

    public GType(char type)
    

    Deze code is waar het galaxy-type is ingesteld, dus we willen het nader bekijken.

  12. Selecteer het pictogram Opnieuw opstarten, dat de knop -knop in de foutopsporingswerkbalk (Ctrl + Shift + F5) om opnieuw te starten.

    Het foutopsporingsprogramma pauzeert op de coderegel waar u het onderbrekingspunt instelt.

  13. Beweeg de muisaanwijzer over de variabele type. U ziet een waarde van S (na de tekencode). Je bent geïnteresseerd in een waarde van I, omdat je weet dat dat een onregelmatig galaxietype is.

  14. Druk op F5- en plaats de muisaanwijzer nogmaals op de variabele type. Herhaal deze stap totdat u een waarde van I in de variabele type ziet.

    Schermopname van het Visual Studio Debugger met een coderegel in geel en een venster met de waarde van de typevariabele van 73 I.

  15. Druk nu op F11 (Debuggen>Binnenstappen).

  16. Druk op F11 totdat u stopt op een coderegel in de switch-instructie voor de waarde 'I' (Select-instructie voor Visual Basic). Hier ziet u een duidelijk probleem dat het gevolg is van een typefout. U had verwacht dat de code verder moest gaan naar de locatie waar MyGType als een onregelmatig galaxytype wordt ingesteld, maar het foutopsporingsprogramma slaat deze code volledig over en onderbreekt de default sectie van de switch-instructie (Else instructie in Visual Basic).

    Schermopname met de spelfout.

    Als u de code bekijkt, ziet u een typefout in de case 'l' instructie. Het moet case 'I'zijn.

  17. Selecteer de code voor case 'l' en vervang deze door case 'I'.

  18. Verwijder het onderbrekingspunt en selecteer vervolgens de knop Opnieuw opstarten om de app opnieuw op te starten.

    De fouten zijn nu opgelost en u ziet de uitvoer die u verwacht.

    Druk op een willekeurige toets om de app te voltooien.

Samenvatting

Wanneer u een probleem ziet, gebruikt u het foutopsporingsprogramma en stapopdrachten zoals F10 en F11 om de coderegio met het probleem te vinden.

Notitie

Als het lastig is om de coderegio te identificeren waar het probleem optreedt, stelt u een onderbrekingspunt in code in die wordt uitgevoerd voordat het probleem zich voordoet en gebruikt u vervolgens stapopdrachten totdat u het probleemmanifest ziet. U kunt ook tracepoints gebruiken om berichten te registreren bij het venster Uitvoer. Door te kijken naar vastgelegde berichten (en te weten welke berichten nog niet zijn geregistreerd!), kunt u vaak de coderegio isoleren met het probleem. Mogelijk moet u dit proces meerdere keren herhalen om het te beperken.

Wanneer u de coderegio met het probleem vindt, gebruikt u het foutopsporingsprogramma om te onderzoeken. Als u de oorzaak van een probleem wilt vinden, inspecteert u de probleemcode tijdens het uitvoeren van uw app in het foutopsporingsprogramma:

  • Inspecteer de variabelen en controleer of ze het juiste type waarden bevatten. Als u een ongeldige waarde vindt, zoekt u uit waar de ongeldige waarde is ingesteld (om te bepalen waar de waarde is ingesteld, moet u het foutopsporingsprogramma mogelijk opnieuw starten, kijken naar de aanroepstackof beide).

  • Controleer of uw toepassing de code uitvoert die u verwacht. (In de voorbeeldtoepassing verwachtten we bijvoorbeeld dat de code voor de switch-instructie het galaxytype instelt op Onregelmatig, maar de app heeft de code overgeslagen vanwege de typfout.)

Fooi

U gebruikt een foutopsporingsprogramma om fouten te vinden. Een tool voor foutopsporing kan fouten alleen voor u vinden als deze de intentie van uw code kent. Een hulpprogramma kan alleen de intentie van uw code kennen als u, de ontwikkelaar, die intentie uitdrukt. Het schrijven van eenheidstests is hoe u dat doet.

Volgende stappen

In dit artikel hebt u enkele algemene concepten voor foutopsporing geleerd. Vervolgens kunt u meer leren over het foutopsporingsprogramma.