Felsökning för absoluta nybörjare
Utan fel gör koden vi skriver som programutvecklare inte alltid vad vi förväntade oss att den skulle göra. Ibland gör det något helt annat! När det oväntade inträffar är nästa uppgift att ta reda på varför, och även om vi kan frestas att bara fortsätta stirra på vår kod i timmar, är det enklare och effektivare att använda ett felsökningsverktyg eller felsökningsprogram.
Ett felsökningsprogram är tyvärr inte något som magiskt kan avslöja alla problem eller "buggar" i vår kod. felsökning innebär att köra koden steg för steg i ett felsökningsverktyg som Visual Studio, för att hitta den exakta punkten där du gjorde ett programmeringsfel. Sedan förstår du vilka korrigeringar du behöver göra i kod- och felsökningsverktygen så att du ofta kan göra tillfälliga ändringar så att du kan fortsätta köra programmet.
Att använda ett felsökningsprogram effektivt är också en färdighet som tar tid och övning att lära sig, men som i slutändan är en grundläggande uppgift för alla programutvecklare. I den här artikeln introducerar vi grundprinciperna för felsökning och ger tips för att komma igång.
Förtydliga problemet genom att ställa dig själv rätt frågor
Det hjälper till att klargöra problemet som du stötte på innan du försöker åtgärda det. Vi förväntar oss att du redan har stött på ett problem i koden, annars skulle du inte vara här och försöka ta reda på hur du felsöker den! Innan du börjar felsöka kontrollerar du att du har identifierat problemet som du försöker lösa:
Vad förväntade du dig att koden skulle göra?
Vad hände i stället?
Om du stöter på ett fel (undantag) när du kör din app kan det vara bra! Ett undantag är en oväntad händelse som uppstår när kod körs, vanligtvis ett fel av något slag. Ett felsökningsverktyg kan ta dig till den exakta plats i koden där undantaget inträffade och kan hjälpa dig att undersöka möjliga korrigeringar.
Vad är problemets symptom om något annat hände? Misstänker du redan var det här problemet uppstod i koden? Om koden till exempel visar text, men texten är felaktig, vet du att dina data antingen är felaktiga eller att koden som anger visningstexten har någon form av bugg. Genom att gå igenom koden i ett felsökningsprogram kan du undersöka varje ändring av variablerna för att identifiera exakt när och hur felaktiga värden tilldelas.
Granska dina antaganden
Innan du undersöker en bugg eller ett fel bör du tänka på de antaganden som gjorde att du förväntade dig ett visst resultat. Dolda eller okända antaganden kan komma i vägen för att identifiera ett problem även när du tittar rätt på orsaken till problemet i ett felsökningsprogram. Du kan ha en lång lista över möjliga antaganden! Här är några frågor att ställa dig själv för att utmana dina antaganden.
Använder du rätt API (dvs. rätt objekt, funktion, metod eller egenskap)? Ett API som du använder kanske inte gör vad du tror att det gör. (När du har undersökt API-anropet i felsökningsprogrammet kan det krävas en resa till dokumentationen för att identifiera rätt API.)
Använder du ett API på rätt sätt? Du kanske använde rätt API men inte använde det på rätt sätt.
Innehåller koden några stavfel? Vissa stavfel, till exempel en enkel felstavning av ett variabelnamn, kan vara svåra att se, särskilt när du arbetar med språk som inte kräver att variabler deklareras innan de används.
Har du gjort en ändring i koden och anta att den inte är relaterad till det problem som du ser?
Förväntade du dig att ett objekt eller en variabel skulle innehålla ett visst värde (eller en viss typ av värde) som skiljer sig från vad som verkligen hände?
Känner du till avsikten med koden? Det är ofta svårare att felsöka någon annans kod. Om det inte är din kod kan du behöva ägna tid åt att lära dig exakt vad koden gör innan du kan felsöka den effektivt.
Tips
När du skriver kod börjar du i liten skala och börjar med kod som fungerar! (Bra exempelkod är till hjälp här.) Ibland är det lättare att åtgärda en stor eller komplicerad uppsättning kod genom att börja med en liten kod som visar den kärnuppgift som du försöker uppnå. Sedan kan du ändra eller lägga till kod stegvis och testa vid varje tidpunkt för fel.
Genom att ifrågasätta dina antaganden kan du minska den tid det tar att hitta ett problem i koden. Du kan också minska tiden det tar att åtgärda ett problem.
Gå igenom koden i felsökningsläge för att ta reda på var problemet uppstod
När du normalt kör en app visas fel och felaktiga resultat först när koden har körts. Ett program kan också avslutas oväntat utan att du får veta varför.
När du kör en app i ett felsökningsprogram, även kallat felsökningsläge, övervakar felsökningsprogrammet aktivt allt som händer när programmet körs. Det gör också att du kan pausa appen när som helst för att undersöka dess tillstånd och sedan gå igenom koden rad för rad för att titta på varje detalj när det händer.
I Visual Studio anger du felsökningsläge med hjälp av F5- (eller Felsökning>Starta felsökning menykommandot eller knappen Starta felsökning i verktygsfältet felsökning). Om några undantag inträffar tar Visual Studios undantagshjälp dig till den exakta punkt där undantaget inträffade och ger annan användbar information. Mer information om hur du hanterar undantag i koden finns i felsökningstekniker och verktyg.
Om du inte fick något undantag har du förmodligen en bra uppfattning om var du ska leta efter problemet i koden. Det här steget är där du använder brytpunkter med felsökningsprogrammet för att ge dig själv en chans att undersöka koden mer noggrant. Brytpunkter är den mest grundläggande och viktiga funktionen för tillförlitlig felsökning. En brytpunkt anger var Visual Studio ska pausa koden som körs så att du kan ta en titt på värdena för variabler, eller minnesbeteendet, sekvensen där koden körs.
I Visual Studio kan du snabbt ange en brytpunkt genom att klicka på vänstermarginalen bredvid en kodrad. Eller placera markören på en rad och tryck på F9.
För att illustrera dessa begrepp tar vi dig igenom en exempelkod som redan har flera buggar. Vi använder C#, men felsökningsfunktionerna gäller för Visual Basic, C++, JavaScript, Python och andra språk som stöds. Exempelkod för Visual Basic tillhandahålls också, men skärmbilder finns i C#.
Skapa en exempelapp (med några buggar)
Sedan skapar du ett program som har några buggar.
Visual Studio måste vara installerat och .NET-skrivbordsutveckling arbetsbelastning installerad.
Om du inte redan har installerat Visual Studio går du till Visual Studio-nedladdningar sidan för att installera den kostnadsfritt.
Om du behöver installera arbetsbelastningen men redan har Visual Studio väljer du Verktyg>Hämta verktyg och funktioner. Visual Studio Installer startas. Välj arbetsbelastningen .NET-skrivbordsutveckling och välj sedan Ändra.
Öppna Visual Studio.
I startfönstret väljer du Skapa ett nytt projekt. Skriv -konsolen i sökrutan, välj antingen C# eller Visual Basic som språk och välj sedan Console App för .NET. Välj Nästa. Skriv ConsoleApp_FirstApp som projektnamn och välj Nästa.
Om du använder ett annat projektnamn måste du ändra namnområdesvärdet så att det matchar projektnamnet när du kopierar exempelkoden.
Välj antingen det rekommenderade målramverket eller .NET 8 och välj sedan Skapa.
Om du inte ser projektmallen Console App för .NET går du till Tools>Hämta verktyg och funktioner, som öppnar Installationsprogrammet för Visual Studio. Välj arbetsbelastningen .NET-skrivbordsutveckling och välj sedan Ändra.
Visual Studio skapar konsolprojektet, som visas i Solution Explorer i det högra fönstret.
I Program.cs (eller Program.vb) ersätter du all standardkod med följande kod. (Välj rätt språkflik först, antingen C# eller 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} } }
Vår avsikt med den här koden är att visa galaxens namn, avståndet till galaxen och galaxtypen allt i en lista. För att felsöka är det viktigt att förstå avsikten med koden. Här är formatet för en rad från listan som vi vill visa i utdata:
galaxnamn, avstånd, galaxytyp.
Kör appen
Tryck på F5 eller knappen Starta felsökning i verktygsfältet Felsökning ovanför kodredigeraren.
Appen startar och det finns inga undantag som visas för oss av felsökningsprogrammet. De utdata som visas i konsolfönstret är dock inte vad du förväntar dig. Här är de förväntade utdata:
Tadpole 400, Spiral
Pinwheel 25, Spiral
Cartwheel, 500, Lenticular
Small Magellanic Cloud .2, Irregular
Andromeda 3, Spiral
Maffei 1, Elliptical
Men du ser dessa utdata i stället:
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
När vi tittar på utdata och vår kod vet vi att GType
är namnet på klassen som lagrar galaxtypen. Vi försöker visa den faktiska galaxtypen (till exempel "Spiral"), inte klassnamnet!
Felsöka appen
Infoga en brytpunkt när appen fortfarande körs.
I
foreach
-loopen högerklickar du bredvid metodenConsole.WriteLine
för att hämta snabbmenyn och väljer Brytpunkt>Infoga brytpunkt från den utfällbara menyn.foreach (Galaxy theGalaxy in theGalaxies) { Console.WriteLine(theGalaxy.Name + " " + theGalaxy.MegaLightYears + ", " + theGalaxy.GalaxyType); }
När du anger brytpunkten visas en röd punkt i vänstermarginalen.
När du ser ett problem i utdata börjar du felsöka genom att titta på föregående kod som anger utdata i felsökningsprogrammet.
Välj ikonen Starta om
knappen i verktygsfältet Felsökning (Ctrl + Shift + F5).
Appen pausar vid den brytpunkt som du anger. Den gula markeringen anger var felsökaren är pausad (den gula kodraden har ännu inte körts).
Hovra över variabeln
GalaxyType
till höger och expandera sedantheGalaxy.GalaxyType
till vänster om skiftnyckelikonen. Du ser attGalaxyType
innehåller en egenskapMyGType
och egenskapsvärdet är inställt påSpiral
."Spiral" är det värde du faktiskt förväntade dig att skriva ut till konsolen! Så det är en bra början att du kan komma åt värdet i den här koden när du kör appen. I det här scenariot använder vi fel API. Nu ska vi se om du kan åtgärda detta när du kör kod i felsökningsprogrammet.
I samma kod, medan du fortfarande felsöker, placerar du markören i slutet av
theGalaxy.GalaxyType
och ändrar den tilltheGalaxy.GalaxyType.MyGType
. Även om du kan göra redigeringen visar kodredigeraren ett fel (röd vågig rad). (I Visual Basic visas inte felet och det här avsnittet av koden fungerar.)Tryck på F11 (Felsök>Steg in i eller knappen Steg in i i verktygsfältet Felsökning) för att köra den aktuella kodraden.
F11 avancerar felsökningsprogrammet (och kör kod) en instruktion i taget. F10 (Step Over) är ett liknande kommando och båda är användbara när du lär dig hur du använder felsökningsprogrammet.
När du försöker gå vidare i debuggern visas dialogrutan Hot Reload, som anger att redigeringar inte kan kompileras.
Dialogrutan Redigera och fortsätt visas som anger att redigeringar inte kan kompileras.
Notis
Om du vill felsöka Visual Basic-exempelkoden hoppar du över de kommande stegen tills du uppmanas att klicka på ikonen Starta om
knappen.
Välj Redigera i meddelanderutan Snabb omstart eller Redigera och Fortsätt. Nu visas ett felmeddelande i fönstret fellista. Felet anger att
'object'
inte innehåller någon definition förMyGType
.Även om vi anger varje galax med ett objekt av typen
GType
(som har egenskapenMyGType
) känner felsökaren inte igen dettheGalaxy
objektet som ett objekt av typenGType
. Vad är det som händer? Du vill titta igenom all kod som anger galaxtypen. När du gör detta ser du att klassenGType
definitivt har egenskapenMyGType
, men något är inte rätt. Felmeddelandet omobject
visar sig vara ledtråden. till språktolkaren verkar typen vara ett objekt av typenobject
i stället för ett objekt av typenGType
.När du tittar igenom din kod som är relaterad till att ange galaxy-typen, hittar du egenskapen
GalaxyType
för klassenGalaxy
anges somobject
i stället förGType
.public object GalaxyType { get; set; }
Ändra föregående kod enligt följande:
public GType GalaxyType { get; set; }
Välj ikonen Starta om
i verktygsfältet Felsökning (Ctrl + Skift + F5) för att kompilera om koden och starta om.
Nu när felsökningsprogrammet pausar på
Console.WriteLine
kan du hovra övertheGalaxy.GalaxyType.MyGType
och se att värdet är korrekt inställt.Ta bort brytpunkten genom att klicka på brytpunktscirkeln i vänstermarginalen (eller högerklicka och välj Brytpunkt>Ta bort brytpunkt) och tryck sedan på F5 för att fortsätta.
Appen kör och visar utdata. Det ser bra ut, men du märker en sak. Du förväntade dig att den lilla magellanska molngalaxen skulle dyka upp som en oregelbunden galax i konsolens utdata, men den visar ingen galaxtyp alls.
Tadpole 400, Spiral Pinwheel 25, Spiral Cartwheel, 500, Lenticular Small Magellanic Cloud .2, Andromeda 3, Spiral Maffei 1, Elliptical
Ange en brytpunkt på den här kodraden före
switch
-instruktionen (föreSelect
-instruktionen i Visual Basic).public GType(char type)
Den här koden är där galaxy-typen anges, så vi vill ta en närmare titt på den.
Välj ikonen Starta om
knappen i Debug-verktygsfältet (Ctrl + Shift + F5) för att starta om.
Felsökningsprogrammet pausar på den kodrad där du anger brytpunkten.
Hovra över variabeln
type
. Du ser värdetS
(efter teckenkoden). Du är intresserad av värdetI
, eftersom du vet att det är en oregelbunden galaxtyp.Tryck på F5 och hovra över variabeln
type
igen. Upprepa det här steget tills du ser värdetI
i variabelntype
.Tryck nu på F11 (Felsöka>Steg in i).
Tryck på F11 tills du stannar på kodraden i
switch
-instruktionen för värdet "I" (Select
-instruktion för Visual Basic). Här ser du ett tydligt problem som beror på ett skrivfel. Du förväntade dig att koden skulle gå vidare till den plats där den angerMyGType
som en oregelbunden galaxtyp, men felsökningsprogrammet hoppar i stället över koden helt och pausar i avsnittetdefault
iswitch
-instruktionen (Else
-instruktionen i Visual Basic).När du tittar på koden visas ett stavfel i
case 'l'
-instruktionen. Det bör varacase 'I'
.Välj i koden för
case 'l'
och ersätt den medcase 'I'
.Ta bort brytpunkten och välj sedan knappen Starta om för att starta om appen.
Buggarna har åtgärdats nu och du ser de utdata du förväntar dig!
Tryck på valfri tangent för att slutföra appen.
Sammanfattning
När du ser ett problem använder du kommandona felsökare och steg till exempel F10 och F11 för att hitta kodområdet med problemet.
Notis
Om det är svårt att identifiera den kodregion där problemet uppstår anger du en brytpunkt i koden som körs innan problemet uppstår och använder sedan stegkommandon tills du ser problemmanifestet. Du kan också använda spårningspunkter för att logga meddelanden till utdatafönstret . Genom att titta på loggade meddelanden (och märka vilka meddelanden som ännu inte loggats!) kan du ofta isolera kodområdet med problemet. Du kan behöva upprepa den här processen flera gånger för att begränsa den.
När du hittar kodregionen med problemet använder du felsökningsprogrammet för att undersöka det. Om du vill hitta orsaken till ett problem kontrollerar du problemkoden när du kör appen i felsökningsprogrammet:
Granska variabler och kontrollera om de innehåller den typ av värden som de ska innehålla. Om du hittar ett felaktigt värde tar du reda på var det felaktiga värdet angavs (för att ta reda på var värdet angavs kan du behöva starta om felsökningsprogrammet, titta på -anropsstackeneller båda).
Kontrollera om programmet kör den kod som du förväntar dig. (I exempelprogrammet förväntade vi oss till exempel att koden för
switch
-instruktionen skulle ange galaxtypen till Oregelbunden, men appen hoppades över koden på grund av stavfelet.)
Tips
Du använder ett felsökningsprogram för att hitta buggar. Ett felsökningsverktyg kan hitta buggar åt dig bara om det känner till avsikten med din kod. Ett verktyg kan bara känna till avsikten med din kod om du, utvecklaren, uttrycker den avsikten. Att skriva enhetstester är sättet att göra det.
Nästa steg
I den här artikeln har du lärt dig några allmänna felsökningskoncept. Sedan kan du börja lära dig mer om felsökningsprogrammet.