Incorrect Line Number Information

For some strange reason, which probably was a search path difference between my machines, I ran into a problem with incorrect line number information yesterday, but at first only on my work machine. When instrumenting java.lang.Thread.start(), the instrumentor lamented about a program counter (PC) value that was out of range. For a very short method, it was asking for a PC of 7, and several other values, up to 43 or so. Of course, they didn’t exist, so the instrumentor failed.

The problem was that the original method, which did have PCs up into that range, was replaced by a much shorter wrapper, but the line number information was kept around. I had thought of that problem, and code was there, but it didn’t work. I was comparing instances and not names (pretty much == vs. .equals()). I don’t know why it never got tested up to this point. Anyway, this is fixed now.

I also realized that I’ll probably have to instrument a few of my system classes, like InstrumentingClassLoader, in a different way. Their code should be invisible to the monitor, so no synchronization points should be queued up whule they are executing. However, some methods in java.lang.Thread are renamed and replaced by wrapper methods that also make the necessary calls to produce synchronization points.

Let’s look at the different events and the way they are instrumented. There are events generated by methods that get instrumented locally — there’s no effect on the callers:

  • Thread.start
  • Thread.exit
  • Thread.interrupt
  • Thread.stop
  • Thread.destroy
  • Thread.setPriority
  • Thread.join (enter/leave)
  • Then there are events that need to be instrumented globally — the callers call a different method because the method cannot be renamed:

  • Thread.sleep (enter/leave)
  • Thread.yield (enter/leave)
  • Object.notify
  • Object.notifyAll
  • Object.wait (enter/leave)
  • And then there are the remaining events:

  • synchronized blocks (try/enter/leave)
  • synchronized (non-static) methods (try/enter/leave)
  • synchronized static methods (try/enter/leave)
  • The last group of instrumentations shouldn’t happen for my system classes, period. The second group can also just be left out. That means the classes call the original methods and no synchronization points will be generated — just what I want. The first group, however, causes problems: If I carry out the instrumentation as with other classes, then the wrapper methods will be called and synchronization points will be queued up. I also can’t leave away the instrumentation since it’s local; the instrumentation only happens inside the callee.

    This means that for the events in the first group, I’ll have to create a special instrumentor that will “undo” the instrumentation just for a select few classes.


    About Mathias

    Software development engineer. Principal developer of DrJava. Recent Ph.D. graduate from the Department of Computer Science at Rice University.
    This entry was posted in Concurrent Unit Testing. Bookmark the permalink.

    Leave a Reply