Ok, so I’ve definitely been having a bad conscience for not writing. It’s not like I haven’t done any work, but I have to admit that I haven’t worked on the concurrent unit testing project since my accident. The week before that I was just gearing up to work on it again, after the hurricane. After the accident, for about three weeks, pretty much all through October, my back was hurting when I was sitting. It still stings a little bit now every once in a while. I just found it hard to work on a project like this that required working in long stretches.
So instead, I added an interesting part to the Rice Marine Biology Simulation. The simulation was already able to protect against fish that use System.exit
, call thread or system functions, and cause a heap or stack overflow. The only thing I couldn’t really do anything against was a fish that diverged without using up any resources.
Initially I had thought about putting each fish into its own thread, and then killing the thread after a certain amount of time had passed. The problem with this is the way thread killing is implemented in Java: If I tell a thread to die, it is forced to throw a ThreadDeath
exception at the next opportunity. However, ThreadDeath
implements Throwable
and can thus be caught. Therefore, it is possible to write a fish that diverges, catches the code>ThreadDeath that is supposed to kill it, and continues to diverge. At that point, I gave up.
After having worked on my bytecode scanning and rewriting framework for the concurrent unit testing project so much, I realized there’s another perspective: I can scan the fish classes being loaded for catch
statements that are so general they might catch a Throwable
, Error
, or ThreadDeath
, and if the user attempts to load such a class, prevent it. That means the fish that does get loaded has no way to prevent ThreadDeath
from unwinding the stack and eventually killing the fish.
This is what I implemented. The actualy scanner was really easy to write. Writing and integrating the class loader was a lot more difficult. In Java, if the same class files is loaded by two different class loaders, the classes in memory are treated as different. Unfortunately, Java doesn’t provide a way to find out if a class has already been loaded by another class loader. I would have liked to know if a class has already been loaded by the system class loader so it doesn’t have to be checked anymore, but that wasn’t possible. Now I scan every class except for a select class of trusted classes. The new system is pretty cool, I think.
I was told in C#, it’s possible to deactivate the ability to catch its equivalent of the ThreadDeath
exception, so such a class loader and scanner wouldn’t be necessary in a C# implementation.
I’ve also written a few thousand words for our OOP book. There’s still lots of work to do, though. We’re working with my temperature conversion examples, but we realized the step from the third iteration (built-in functions with quadratic growth) to the fourth iteration (lambdas, linear growth) is too steep. So we’ll throw in a shape example to familiarize the reader with abstract classes and inheritance first. I’ve been working on that, but haven’t had the time. I would like to write more, but I need to focus on other things.
One last piece of good news: The OOP/OOD workshop that Dr. Nguyen, Dr. Wong, Eric Cheng, and I have submitted to SIGCSE 2006, this time to be held here in beautiful Houston, has been accepted. So eventually we’ll have to work on that, but we’ll try to create as much overlap with the book as possible.
I finished lots of grading yesterday and today. And now I really have to dive into CUnit again…