[Oberon] PO: Illegal memory access in GC
Andreas Pirklbauer
andreas_pirklbauer at yahoo.com
Fri May 15 12:59:25 CEST 2020
> The reason for the illegal memory read lies within the
> garbage collector in module Kernel.Mod.
PS: Below is one possible fix for PO 2013 and Extended Oberon.
Only procedure Kernel.Mark needs to be modified in two places
-ap
PO 2013:
~~~~~~~
PROCEDURE Mark*(pref: LONGINT);
VAR pvadr, offadr, offset, tag, p, q, r: LONGINT;
BEGIN SYSTEM.GET(pref, pvadr); (*pointers < heapOrg considered NIL*)
WHILE pvadr # 0 DO SYSTEM.GET(pvadr, p);
IF p >= heapOrg THEN SYSTEM.GET(p-4, offadr);
IF offadr = 0 THEN q := p; (*mark elements in data structure with root p*)
REPEAT SYSTEM.GET(p-4, offadr);
IF offadr = 0 THEN SYSTEM.GET(p-8, tag); offadr := tag + 16 ELSE INC(offadr, 4) END ;
SYSTEM.PUT(p-4, offadr); SYSTEM.GET(offadr, offset);
IF offset # -1 THEN (*down*)
SYSTEM.GET(p+offset, r);
IF r >= heapOrg THEN SYSTEM.GET(r-4, offadr);
IF offadr = 0 THEN SYSTEM.PUT(p+offset, q); q := p; p := r END
END
ELSE (*up*) SYSTEM.GET(q-4, offadr); SYSTEM.GET(offadr, offset);
IF p # q THEN SYSTEM.GET(q+offset, r); SYSTEM.PUT(q+offset, p); p := q; q := r END
END
UNTIL (p = q) & (offset = -1)
END
END ;
INC(pref, 4); SYSTEM.GET(pref, pvadr)
END
END Mark;
EO:
~~~
PROCEDURE Mark*(pref: LONGINT);
VAR pvadr, offadr, offset, tag, p, q, r, pos, len, elemsize, blktyp: LONGINT;
BEGIN SYSTEM.GET(pref, pvadr); (*pointers < heapOrg considered NIL*)
WHILE pvadr # 0 DO SYSTEM.GET(pvadr, p);
IF p >= heapOrg THEN SYSTEM.GET(p-4, offadr);
IF offadr = 0 THEN q := p; (*mark elements in data structure with root p*)
REPEAT SYSTEM.GET(p-4, offadr); SYSTEM.GET(p-8, tag); blktyp := tag MOD 4;
IF blktyp = 0 THEN (*record*) pos := p;
IF offadr = 0 THEN offadr := tag + 16 ELSE INC(offadr, 4) END ;
SYSTEM.PUT(p-4, offadr); SYSTEM.GET(offadr, offset)
ELSIF blktyp = 1 THEN (*array of record*)
IF offadr = 0 THEN offadr := tag + 15; pos := p + 16; SYSTEM.PUT(p+12, pos) ELSE INC(offadr); SYSTEM.GET(p+12, pos) END ;
SYSTEM.GET(offadr, offset);
IF offset = -1 THEN SYSTEM.GET(p, len); SYSTEM.GET(p+4, elemsize); INC(pos, elemsize);
IF pos < p + 16 + len*elemsize THEN offadr := tag + 15; SYSTEM.GET(offadr, offset); SYSTEM.PUT(p+12, pos) END
END ;
SYSTEM.PUT(p-4, offadr)
ELSIF blktyp = 2 THEN (*array of pointer*) pos := p + 16;
IF offadr = 0 THEN offset := 0; SYSTEM.PUT(p-4, p+12) (*offadr*)
ELSE SYSTEM.GET(p, len); SYSTEM.GET(p+12, offset); INC(offset, 4);
IF offset >= len*4 THEN offset := -1 END
END ;
SYSTEM.PUT(p+12, offset)
ELSE (*array of basic type (tag = 3) or array of procedure (tag = 7)*)
offset := -1; SYSTEM.PUT(p+12, -1); SYSTEM.PUT(p-4, p+12) (*offadr*)
END ;
IF offset # -1 THEN (*down*)
SYSTEM.GET(pos+offset, r);
IF r >= heapOrg THEN SYSTEM.GET(r-4, offadr);
IF offadr = 0 THEN SYSTEM.PUT(pos+offset, q); q := p; p := r END
END
ELSE (*up*) SYSTEM.GET(q-4, offadr); SYSTEM.GET(offadr, offset);
IF p # q THEN SYSTEM.GET(q-8, tag); blktyp := tag MOD 4;
IF blktyp = 0 THEN pos := q ELSIF blktyp = 1 THEN SYSTEM.GET(q+12, pos) ELSE pos := q + 16 END ;
SYSTEM.GET(pos+offset, r); SYSTEM.PUT(pos+offset, p); p := q; q := r
END
END
UNTIL (p = q) & (offset = -1)
END
END ;
INC(pref, 4); SYSTEM.GET(pref, pvadr)
END
END Mark;
More information about the Oberon
mailing list