nästa upp förra innehåll
Nästa: Vanliga exekveringsfel Upp: Hur man kompilerar ett Förra: Vanliga kompileringsfel

Felmeddelanden vid exekveringen

Även under exekvering av program kan man få felmeddelanden, så kallade exekveringsfel. Det kan till exempel inträffa när man försöker läsa från en fil som inte finns eller försöker följa en pekare som är NIL.

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.


nästa upp förra innehåll
Nästa: Vanliga exekveringsfel Upp: Hur man kompilerar ett Förra: Vanliga kompileringsfel

Viggo Kann
Fri Aug 7 00:55:14 MET DST 1998