Re: [MLton] Crash in GC

"Chris Cannam" <[email protected]> Sun, 06 Nov 2022 19:04:01 +0000
Newsgroups gmane.comp.lang.ml.mlton.devel
Message-ID <[email protected]>
On Sun, 6 Nov 2022, at 15:52, Matthew Fluet wrote:
> If the address of the bad intergenerational pointer is consistent 
> between runs

It is.

> set a hardware watchpoint on the address 
> that will be written with the pointer into the nursery and then look at 
> the C/assembly that immediately follows the write; that should mark a 
> corresponding card.

According to gdb, and using the C-codegen output, the last two writes to that address before the failing GC are:

 * initialisation to 1 from GC_sequenceAllocate:87, then
 * updating to another value (3436048) in line 33191 of this code:

 33184		Frontier = CPointer_add (Frontier, (Word64)(0x28ull));
 33185		O(Word64, T(P, 1), 0) = S(Word64, 128);
 33186		O(Real64, T(P, 1), 8) = S(Real64, 136);
 33187		O(Real64, T(P, 1), 16) = S(Real64, 144);
 33188		O(Word32, T(P, 1), 24) = T(W32, 0);
 33189		T(W64, 0) = WordU64_rshift ((Word64)S(Objptr, 112), (Word32)(0x8ull));
 33190		X(Word8, O(CPointer, GCState, 936), T(W64, 0), 1, 0) = (Word8)(0x1ull);
 33191		X(Objptr, S(Objptr, 112), S(Word64, 88), 8, 0) = T(P, 1);
 33192		T(W64, 1) = Word64_add (S(Word64, 88), (Word64)(0x1ull));
 33193		S(Word64, 88) = T(W64, 1);
 33194		goto loop_277;
 33195	
 33196	loop_277:
 33197		T(W32, 0) = WordS64_lt (S(Word64, 88), S(Word64, 104));
 33198		if (T(W32, 0)) goto L_9521; else goto L_9522;
 33199	
 33200	L_9522:
 33201		O(Word64, S(Objptr, 112), -8) = (Word64)(0x1Dull);
 33202		T(W64, 0) = WordU64_rshift ((Word64)S(Objptr, 0), (Word32)(0x8ull));
 33203		X(Word8, O(CPointer, GCState, 936), T(W64, 0), 1, 0) = (Word8)(0x1ull);
 33204		X(Objptr, S(Objptr, 0), S(Word64, 40), 8, 0) = (Objptr)S(Objptr, 112);
 33205		T(W64, 1) = Word64_add (S(Word64, 40), (Word64)(0x1ull));
 33206		S(Word64, 40) = T(W64, 1);
 33207		goto loop_278;

I checked at the watchpoint and (as in line 33191) StackTop+112 does indeed contain the nursery pointer address, so this looks like the right thing.

Then the conditional branch at line 33198 is not taken, so execution goes on to L_9522 below it. Lines 33202-33204 look like it could possibly be card-marking? But this is making my head hurt a little, so I may have to come back to it.

If I continue from that watchpoint, the next thing that happens is the failed invariant check.

Is it possible to get any more annotation in the C output, about which bit of the source something in the output might correspond to?


Chris