On Sat, Apr 27, 2002 at 05:06:08PM -0400, Mike Lambert wrote: > > For (1), maybe we should add an opcode: get_number_of_live_objects? > > Then you could write a test case that records the number of live > > objects, does stuff, forces a sweep and collect, and checks that the > > saved number + #expected live objects is equal to the currently live > > number? > > I agree this kind of testing is needed. It doesn't cause parrot to crash > and burn like other bugs do, but it's still just as bad in the long run. > The problem is that currently, these types of tests are not doable via > opcodes. There was some talk about allowing for C-programs to participate > in the test suite as part of the make process awhile ago, but nothing > came of it. > > There are lots of things we aren't testing, and making opcodes for every > possible thing so we can test them is going to be painful (sprintf, for > example...opcodes can't take a variable number of arguments.)
I was sort of planning on making PMCs for them instead -- a PMC for each of the various stacks, a PMC for the operating system, maybe a PMC for the garbage collector. And one PMC for the interpreter: One PMC to rule them all, One PMC to find them. One PMC to bring them all, And in the darkness bind them to keys so you can use keyed lookup ops like set P1, P0["user stack"]. (My deepest apologies to Dr. Tolkien). All of them would be read-only for the most part. > > For (2), a compile option that scribbles 010101010101... all over > > collected objects? It's not perfect, but it would make it quite a bit > > less likely for mistakes to slip by. > > This isn't any better, I don't think. The fundamental problem is > that we want to avoid read OR writes to memory that's not > available for use. The above proposal would eliminate most reads > that were using pointers. If I request memory, do something which gets it > collected, then initialize my requested memory, the above apprach will > not help. > > I'm not sure if there's any 100% effective solution to catching these > bugs. It might be useful to punt header allocations down to > mem_sys_allocate when GC_DEBUG is turned on, with the hope that memory > won't get reused nearly as often. DOD runs would still be performed (the > pools would have to store pointers to the memory we've allocated), and > DODing of a header would cause it to be zeroed (or 0101010'ed) out, and > then mem_sys_free'd. > > But yours is certainly much easier and safer to implement. :) What I've done in the past (though it doesn't make as much sense in this context) is to play tricks with the MMU. So, in the painfully slow and bloated debugging mode, each PMC gets its own page, and when PMCs are placed on the free list you mprotect() them to trap reads and writes. It just has limited utility because it burns about 36x as much space as needed for the PMCs, and isn't very portable. (And yes, it's way harder to implement than scribbling over the bits!)