• No results found

Felsökning - Debuggning

Litet om program, villkorssatser, flödeskontroll och funktioner

Uppgift 10 Lös följande ekvationssystem:

7 Felsökning - Debuggning

Nästan inga program blir helt rätt från början. När det uppstår fel i enklare program kan man ofta hitta orsaken bara genom att gå igenom programmet en gång till med vetskap om vad som gick fel. Men i takt med att programmen blir större och mer komplicerade blir denna procedur mer och mer besvärlig och tidskrävande.

Ett fel i ett datorprogram kallas på engelska "bug". Detta uttryck sägs stamma från datorernas barndom, vid ett tillfälle hade ett team som jobbade med en av de första stora beräkningsmaskinerna (rörbestyckad) länge försökt att få vad som gick fel i ett program. Till slut upptäckte man att orsaken inte låg i programmet utan att en död insekt inuti maskinen hade orsakat en kortsluting. Denna historia må vara sann eller inte, men ett fel i ett datorprogram heter på engelska "bug", och processen att hitta och korrigera fel heter de-bugging. På svenska säger man oftast bugg och debugga, men ibland kan man möta termen "avlusa".

För att underlätta denna process finns i de flesta datormiljöer något som kallas de-bugger. Det är ett verktyg som på olika sätt underlättar felsökningen i program. Vi skall i det här kapitlet illustrera hur man kan arbeta med en de-bugger genom att korrigera ett felaktigt program för att beräkna primtalsfaktorer.

7.1 MATLABs de-bugger

Låt oss illustrera processen med hjälp av följande program för att beräkna primtalsfaktorer, skriv in koden i matlab i editor-fönstret.

AntalFaktorer=0;

clear Faktor;

i=2;

while (i < sqrt(x)) kvot = x/i;

rest = i*floor(kvot) - x;

% om rest är noll går divisionen jämnt ut if(rest==0)

AntalFaktorer = AntalFaktorer +1;

Faktor(AntalFaktorer) = i;

end if(i==2) i=i+1;

else

i=i+2;

end end

AntalFaktorer Faktor

Om vi nu i kommandofönstret skriver x=9 för att ladda ned det värdet i workspace och sedan kör programmet, enklast genom att trycka på "save and run"-knappen så ser vi att programmet

uppenbarligen inte fungerar som det var tänkt, AntalFaktor är lika med noll. För att undersöka vad som händer sätter vi en så kallad "break-point" på något lämpligt ställe. En break-point är ett ställe i koden vid vilket programmet stannar upp när det kommit dit. (programmet stannar innan det genomför den instruktion vi satt break-point vid) När vi trycker på "save and run" så startar programmet, men kör inte till slutet, utan gör en paus vid vår definierade "break-point Vi har då möjlighet att via kommandon i kommanofönstret undersöka, eller till och med ändra, värdet på parametrar i programmet, och kan sedan köra vidare genom att trycka på "save and run". Låt oss börja vår undersökning genom att sätta en break-point omdelbart inuti while-loopen, vid raden kvot = x/i;.

Det finns två sätt att sätta en break-point. Du kan antingen markera raden i editor-fönstret och tryck på

"set break-point" knappen: . Ett enklare sätt är att bara klicka på det lilla minustecknet till höger om radnumret. Vi ser att raden markeras

med en röd punkt som anger att en "brak

point" är satt just här. Tryck nu på "save and run" så kör programmet fram till denna rad.. När programmet stannar så ändras prompten i kommando-fönstret till >K för att visa att vi är i debug-mode. Vi kan nu undersöka värdet på våra variabler genom att t.ex. skriva x eller i i kommandofönstret. Gör vi det ser vi att allt verkar normalt, x är 9 och i är 2, precis som förväntat. Vi trycker därför på "save and run" en gång till för att se vad som händer nästa varv i loopen. Hoppsan -vi kom aldrig tillbaks till vår break-point? Varför?

Detta kan vi undersöka med hjälp av en annan av metoderna i debuggern. Starta om programmet från början så att vi stannar vid vår break-point igen. Vi kan nu fortsätta härifrån en rad i taget genom att trycka på "step"-knappen (stegningsknappen): . När vi gör det ser vi hur markeringen stegvis flyttas genom programmet. På så sätt kan vi se exakt i vilken ordning raderna i programmet utförs, vilka delar av villkorssatser som utförs och hur loopar genomförs. Vid varje punkt kan vi undersöka/sätta värdet på variabler i programmet. Genom att stega oss fram från vår break-point kan vi se hur programmet korrekt detekterar att 2 inte är en faktor i 9, hur i stegas upp från 2 till 3 och hur vi sedan testar om 3 är mindre än roten ur 9. Och sedan stegar vi ner till slutet av while-loopen istället för att testa om 9 är delbart med 3. Där har vi felet: villkoret i while-loopen skall vara "<=", inte "<".

Vi korrigerar detta och verifierar att programmet ger rätt resultat. För att slippa stega oss fram tar vidå bort vår tidigare break-point, enklast genom att klicka på den röda punkten.

Tydligen är programmet inte helt avlusat ännu: kör vi får vi svaret:

AntalFaktorer = 1

Faktor = 3

För att reda ut var problemet ligger denna gång sätter vi igen en break-point vid kvot = x/i;;

och undersöker x och i när programmet stannar. Vi ser då genast att variabeln i stegas upp genom 2, 3 och sedan kommer vi inte tillbaka till vår break-point. Tydligen händer något efter i=3 som vi inte önskar. För att få reda på vad kan vi köra igång programmet igen och när vi stannar vid vår break-point så sätter vi i kommandofönstret K>> i=3 för att se hur programmet fortsätter genom att stega oss fram. Vi ser då genast problemet: variabeln stegas upp till 5 utan att testa om 3 förekommer som faktor mer än en gång. Vi måste alltså låta bli att stega upp i de gånger divisionen går jämnt upp för att testa om samma faktor finns mer än en gång. Vi ändrar i vår kod, från :

if(rest==0)

AntalFaktorer = AntalFaktorer +1;

Faktor(AntalFaktorer) = i;

end if(i==2) i=i+1

else i=i+2 end

till

if(rest==0)

AntalFaktorer = AntalFaktorer +1;

Faktor(AntalFaktorer) = i;

else

if(i==2)

i=i+1

else i=i+2 end

end

så att inte stegas upp om den är en faktor i x. Vi tar bort alla break-points och prövar. När vi gör det inträffar något som händer litet då och då: när vi trycker på "return" försvinner prompten och ingenting händer, ingen output, och ingenting händer om vi försöker skriva in kommandon. Oftast är det här beteendet förorsakat av att programmet har hamnat i en oändlig loop där villkoret för att loopen skall avbrytas aldrig blir sant.

För att kunna åtgärda felet måste vi först och främst få MATLAB att sluta med loopandet, det åsatdkommer vi genom att klicka i kommandofönstret och trycka ctrl-Z, dvs vi trycker samtidigt in control-tangenten och z. Som svar på ctrl-Z avbryer MATLAB utförandet av det program som kör och lämnar tillbaka kontrollen till kommandofönstret. Vi kan nu med hjälp av debuggern ge oss i kast med.Uppgift 12 där uppgiften är att dels finna orsaken till den oändliga loopen, dels försöka korrigera det ganska grova felet i programmet.

Mer hjälp om debuggern kan du få i on-line hjälpen via ?/MATLAB/Using MATLAB/Development Environment/Editing and Debugging M-files

Uppgift 12

Använd matlabs debugger för att förstå hur den oändliga loopen uppstår och korrigera programmet så att det på ett korrekt sätt beräknar primtalsfaktorerna i godtyckliga tal.

Related documents