Nästa: Vanliga exekveringsfel
Upp: Hur man kompilerar ett
Förra: Vanliga kompileringsfel
Om det uppstår ett fel när man kör programmet prog så avbryts exekveringen, ett kort meddelande skrivs ut på skärmen och ytterligare information skrivs ner på filen prog.trace. Om filen prog.trace redan finns så läggs informationen till i slutet av filen. Det som står i .trace-filen är dock sällan av intresse.
Som exempel på hur exekveringsfel behandlas tar vi programmet Testprog.p:
PROGRAM Testprog;
TYPE Postpek = ^Post;
Post = RECORD
i: Integer;
next: Postpek;
END;
VAR first: Postpek;
PROCEDURE WriteList(p: Postpek);
BEGIN
Writeln(p^.i);
WriteList(p^.next);
END;
BEGIN
New(first); first^.i := 1;
New(first^.next); first^.next^.i := 2;
first^.next^.next := NIL;
WriteList(first);
END.
Eftersom man har glömt avbrottsvillkoret i den rekursiva proceduren WriteList
kommer programmet att försöka följa pekaren first^.next^.next som
ju är NIL. Utskriften följd av felmeddelandet blir
1
2
Pointer value (0) is out of legal range
*** Testprog terminated by signal 5: SIGTRAP
*** Traceback being written to Testprog.trace
Abort
Dessutom har Testprog.trace fyllts på lite i slutet:
*** Stacktrace of Testprog
*** Program terminated due to SIGTRAP
[3] __PC0__sigdie(0xef4968e4, 0x2075, 0xefffde30, 0xef69f92c, 0x2074, 0x3), at
0xef68b7e4
---- called from signal handler with signal 5 (SIGTRAP) ------
[4] _kill(), at 0xef474340
[5] _kill(0x8, 0xef69f92c, 0x0, 0xef69f92c, 0xb, 0x0), at 0xef474340
[6] __PC0__NIL(0x0, 0x20ea0, 0x20c00, 0x20dfc, 0x0, 0xa), at 0xef6861f0
[7] writelist(p = (nil)), line 11 in "Testprog.p"
[8] writelist(p = 0x219f8), line 12 in "Testprog.p"
[9] writelist(p = 0x219e8), line 12 in "Testprog.p"
[10] program(), line 19 in "Testprog.p"
detaching from process 8308
I tracefilen skrivs information om var i programmet felet inträffade. Inte bara radnumret där felet uppstod anges, utan också vilka procedurer och funktioner som just då var aktiva, och på vilken rad man befann sig i varje procedur och funktion. Detta kallas anropsstacken och är mycket användbart vid avlusning, se också avsnitt 13.5. Varje numrerad rad motsvarar ett proceduranrop. Överst i anropsstacken ligger några systemprocedurer som anropas automatiskt när exekveringsfel inträffar. Under dem hittar du de för tillfället aktiva procedurerna i ditt program med upplysning på vilken rad de var när felet inträffade. I exemplet kan man se att när felet inträffade var huvudprogrammet och tre instanser av proceduren WriteList aktiva.
Fel som upptäcks vid exekveringen är bland annat
| division med noll, |
| försök att följa NIL-pekare, |
| filfel, |
| case-sats-fel, |
| överskridning av det tillåtna minnesområdet, |
| överskridning av maximitalet för Integer32-variabler, |
men tyvärr inte
| variabeltilldelning utanför tillåtet intervall, |
| vektorindexering utanför tillåtet intervall, |
| oinitierade variabler. |
Om man tar med väljaren -C vid kompileringen (vilket run-kommandot gör automatiskt) får man ibland, men inte alltid, felmeddelandet illegal instruction då ett intervall- eller vektorgränsfel inträffar.
Det säkraste sättet att ta reda på var i programmet ett fel uppstod är användning av avlusaren, se avsnitt 13.
Viggo Kann