• No results found

A.9 Formatting

Appendix B

ComsolScripts Debugger

F¨or att underl¨atta fels¨okning i komplicerade programm finns i de flesta datormilj¨oer ett de-bugverktyg som p˚a olika s¨att underl¨attar fels¨okningen i program. Vi skall i det h¨ar kapitlet illustrera hur man kan arbeta med ComsolScripts debugger genom att korrigera ett felaktigt program f¨or att ber¨akna primtalsfaktorer. Programmet s¨oker primtalsfaktorer i variabeln x som antas finnas lagrad i workspace. I variabeln AntalFaktorer lagras hur m˚anga faktorer som finns i x, variabeln Faktor inneh˚aller de olika primtalsfaktorerna

AntalFaktorer=0;

i=2;

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

rest = i*floor(kvot) - x;

% om rest ¨ar noll g˚ar divisionen j¨amnt 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

L¨agg m¨arke till att det inte r¨acker att g˚a upp till i < sqrt(x), om talet har primfaktorer s˚a m˚aste minst en av dem vara l¨agre ¨an roten ur talet, men andra faktorer kan vara st¨orre.

Det r¨acker allts˚a att loopa upp till roten ur x om vi bara vill veta om x ¨ar ett primtal eller inte, men om vi vill hitta alla primfaktorer s˚a m˚aste vi g˚a hela v¨agen.

B.1 Debuggning med breakpoints

L˚at oss illustrera processen med hj¨alp av programmet p˚a f¨oreg˚aende sida f¨or att ber¨akna primtalsfaktorer. Skriv in koden i en m-fil och spara den med namnet prim1.m i den aktuella katalogen.

Om vi nu i kommandof¨onstret skriver x=9 f¨or att ladda ned det v¨ardet i workspace och sedan k¨or programmet, enklast genom att skriva prim1 s˚a ser vi att programmet uppenbarligen inte fungerar som det var t¨ankt, AntalFaktorer ¨ar lika med ett och inte tv˚a. F¨or att unders¨oka

113

vad som h¨ander s¨atter vi en s˚a kallad ”break-point” i programmet. Detta g¨or vi genom att skriva dbstop prim1. Vi kan kontrollera att det fungerar genom att klicka p˚a fliken

“Breakpoints” l¨angst ned i Skrivobrdsf¨onstret. N¨ar vi nu exekverar prim1.m genom att skriva prim1 s˚a g˚ar ComsolScript in i Debug-mod, vilket visas genom att prompten C  byts ut mot D . I debug-mod stannar program-exekveringen d¨ar man satt sin break-point, i det h¨ar fallet i b¨orjan av programmet prim1 (man kan genom att ge kommandot dbstop prim1

# d¨ar # ¨ar en siffra instruera ComsolScript att s¨atta en break-point vid rad # i en given rutin). N¨ar programmet stannar s˚a skrivs f¨orst radnumret och sedan kommandot som ges p˚a den raden ut. Samtidigt ¨oppnas filen i editor-f¨onstret. Genom kommandot dbstep kan vi stega igenom filen steg f¨or steg. Hela tiden kan vi f¨olja med i editorf¨onstret och se hur l˚angt vi kommit i programmet. Vi kan vid varje rad kontrollera v¨ardet p˚a variabler i programmet genom att bara skriva namnet p˚a variabeln, jfr exemplet:

C clear all

prim1 5 rest = i*floor(kvot) - x;

D kvot kvot = 4.5000

Det h¨ar visar n˚agot som ¨ar viktig att komma ih˚ag: n¨ar vi stannar vid en punkt i programmet och ComsolScript skriver ut kommandot i kommandof¨onstret s˚a har kommandot ¨annu inte utf¨orts. S˚a n¨ar vi stannar vid rad 4 s˚a ¨ar kvot ¨annu inte definierad eftersom divisionen inte utf¨orts.

Det kan bli ganska omst¨andigt att stega igenom varje kommando i ett program, ofta vill man ist¨allet t ex stanna till en g˚ang i varje loop. Det kan vi g¨ora genom att utnyttja m¨ojliheten att st¨atta en break-point p˚a godtyckligt st¨alle i en fil. Vi g˚ar ur debug-mode genom att ge dbquit, tar bort v˚ar gamla break-point med dbclear och s¨atter en vid b¨orjan av while-loopen med dbstop prim1 4. N¨ar vi sedan k¨or prim1 stannar ComsolScript i debug-mod vid rad 4, dvs f¨orsta g˚angen vi ¨ar “inuti” while-loopen. Vi kan nu unders¨oka v¨ardet p˚a v˚ara variabler genom att t.ex. skriva x eller i i kommandof¨onstret. G¨or vi det ser vi att allt verkar normalt, x ¨ar 9 och i ¨ar 2, precis som f¨orv¨antat. Vi forts¨atter nu genom att ge

B.1. DEBUGGNING MED BREAKPOINTS 115 kommandot dbcont. Det kommandot inneb¨ar att exekveringen av programmet forts¨atter tills man kommer fram till n¨asta break-point (det g˚ar bra att s¨atta mer ¨an en break-point i ett program). Vi ger dbcont en g˚ang till f¨or att se vad som h¨ander n¨asta varv i loopen. Vi ser att i stegas upp till 3, x ¨ar fortfarande 9, vi tar ett varv till och finner x = 9, i = 5 och AntalFaktorer = 1. H¨ar har vi felet! Programmet har visserligen “sett” att 3 ¨ar en faktor i nio, men vi testar inte om faktorn finns mer ¨an en g˚ang: variabeln stegas upp till 5 utan att testa om 3 f¨orekommer som faktor mer ¨an en g˚ang. Vi m˚aste allts˚a l˚ata bli att stega upp i

s˚a att inte i stegas upp om den ¨ar en faktor i x. Vi korrigerar detta och verifierar att programmet ger r¨att resultat. F¨or att slippa stega oss fram tar vi d˚a bort v˚ar tidigare break-point, enklast genom att skriva dbclear, clear all f¨oljt av x = 9 och k¨or sedan genom att ge prim1: N¨ar vi g¨or det intr¨affar n˚agot som h¨ander litet d˚a och d˚a: n¨ar vi trycker p˚a return f¨orsvinner prompten och ingenting h¨ander, ingen output, och ingenting h¨ander om vi f¨ors¨oker skriva in kommandon. Oftast ¨ar det h¨ar beteendet f¨ororsakat av att programmet har hamnat i en o¨andlig loop d¨ar villkoret f¨or att loopen skall avbrytas aldrig blir sant.

F¨or att kunna ˚atg¨arda felet m˚aste vi f¨orst och fr¨amst f˚a ComsolScript att sluta med loopan-det, det ˚astadkommer vi genom att klicka i kommandof¨onstret och trycka ctrl-C, dvs vi trycker samtidigt in control-tangenten och c. Som svar p˚a ctrl-C avbryter ComsolScript utf¨orandet av det program som k¨or och l¨amnar tillbaka kontrollen till kommandof¨onstret. Vi g¨or clear all f¨or att bli av med eventuellt skr¨ap och s¨atter x=9. Vi kan unders¨oka var felet ligger med hj¨alp av en annan av metoderna i debuggern. S¨att tillbaks en break-point p˚a samma st¨alle och skriver prim1 stannar vi vid v˚ar break-point igen.

Vi kan nu forts¨atta h¨arifr˚an en rad i taget genom skriva dbstep. N¨ar vi g¨or det flyttas vi stegvis genom programmet. Det h¨ar illustrerar ett annat s¨att att utnyttja debuggern, vi kan se exakt i vilken ordning raderna i programmet utf¨ors - speciellt som den aktuella raden alltid visas i editor-f¨onstret - och p˚a s˚a s¨att se exakt hur vi r¨or oss genom komplicerade if-strukturer. Vid varje punkt kan i programmet kan vi dessutom som vanligt unders¨oka/s¨atta v¨ardet p˚a variabler i programmet. M¨ark ocks˚a att n¨ar vi ¨ar inne i debuggern s˚a kan vi fliken

“DEbug” l¨angst ned p˚a skrivbordet f˚a upp knappar f¨or de vanligaste kommandona och t.ex.

stega fram bara genom att klicka med musknappen. Genom att stega oss fram fr˚an v˚ar

break-point kan vi se hur programmet korrekt detekterar att 2 inte ¨ar en faktor i 9, hur i stegas upp fr˚an 2 till 3 och hur vi sedan testar om 3 ¨ar en faktor i 9. Efter att ha “sett” att s˚a ¨ar fallet, och korrekt stegat upp AntalFaktorer forts¨atter programmet, och eftersom tre var en faktor stegas i inte upp.

Du skall nu med hj¨alp av debuggern ge dig i kast med ¨ovningsuppgift 1 d¨ar uppgiften ¨ar att genom att forts¨atta att stega dig fram˚at dels finna orsaken till den o¨andliga loopen, dels f¨ors¨oka korrigera ytterligare ett ˚aterst˚aende fel i programmet som g¨or att ¨aven n¨ar du kurerat den o¨andliga loopen s˚a f˚ar vi fortfarande inte r¨att svar f¨or antalet faktorer.

Mer hj¨alp om debuggern kan du f˚a i on-line hj¨alpen via ?/ComsolScript/The Program-ming Language/Debugging/Debug Commands