[gclist] Allowing finalizers to wait for the messiah.
Thu, 22 May 1997 09:46:39 -0500
>If I had time, I'd tell you in detail, but I don't. Basic
>idea, if you have optional finalization, is to keep a table
>full of "hidden" pointers (either "encrypted", or simply explicitly
>not scanned by the GC). After the GC runs, the table must be
>checked for each about-to-be freed cell, and those found in the
>table, are placed in a queue (accessible to the garbage collector,
>now) and the elements in the queue are processed by running
>their finalizers. Details, such as answers to "what order is
>used to place elements in the queue?" and "what do you do if
>A and B are on the finalizer queue, and running A's finalizer
>makes B reachable from an ordinary root?" seem to provoke long
>and fruitless (no consensus is ever reached) debate.
You've missed the ugliest question. What if a finalizer stores
a pointer to its object. You now have a pointer to free space.
Consider this in the context of Java. Java makes the promise
that you can't write a virus in Java. This is the whole point
of the language. You can have Java apps in your web site and
people can download them and they wont take over.
So I write an app that allocates an object which contains a
large byte array and a finalizer. The finalizer comes along
and stores a pointer to the array in a static area. Now the
program keeps running building objects and watching the array
until an object shows up inside it. Java objects have pointers
to machine language functions but you can't normally see or
change them. But now you have this Java object inside a byte
array. So you aim one of those pointers to your own machine
language and trigger it via its object's methods. Now your
virus takes over.
At minimum a finalizer must fill the following requirements.
Safe. You can't use one to create a pointer to free space.
General. You can put any legal code in one.
The following requirements are valuable.
Sure. If you build an object with a finalizer that finalizer
will get run even if only at end of job.
Prompt. Your job doesn't have to run a billion years to
get its finalizers run. You aren't running one
finalizer per collection cycle.
The following requirement is optional.
Ordered. You can decide the order of your finalizers.
But there is no substitute for the first two requirements
and you blew the first one but got two, three and four.
I believe all five can be met but its expensive. The
first two must be met, failure is not an option. If
the only way to meet them is never to run finalizers
saying "They aren't prompt so they're waiting for the
messiah" that is the correct implementation. You will
have fewer hard to reproduce bugs that way and your
code will be smaller and faster. At least until the
messiah comes and all these untested finalizers run
for the first time long after your program has died.
Charles Fiterman Geodesic Systems
414 North Orleans Suite 410 Phone 312 832 1221 x223
Chicago IL 60610-4418 FAX 312 832 1230
A young man saw a product advertised in a magazine that said
"Guaranteed 100% effective against bugs when properly used."
He sent away and got two blocks of wood with the instructions
"Place bug on block A, strike sharply with block B." Debuggers
are like that, and you can get stung while using them. Great
Circle tries to be something better than that.