Monday, July 28, 2008

Obligation analysis data

Here are the FindBugs analysis results files for my recent use of obligation analysis to look for unclosed stream bugs in Vuze and jEdit:

http://faculty.ycp.edu/~dhovemey/findbugs/vuze-obl.fba
http://faculty.ycp.edu/~dhovemey/findbugs/jedit-obl.fba

I classified the warnings as NEEDS_ANALYSIS if I considered the code apparently correct, and the warning could be avoided through the use of annotations (@WillClose, @WillCloseWhenClosed, etc.) These were cases where if a called method (or object) failed to close the stream, then there truly would be a bug.

I classified warnings as SHOULD_FIX if I considered that it was possible for the code to fail to close a stream.

I classified the warnings as ANALYSIS_ERROR if the warning was completely erroneous.

Friday, July 25, 2008

Obligation analysis: success!

The implementation of obligation analysis in FindBugs seems to be in a useful state.

The analysis found about 8 bugs related to unclosed streams in FindBugs itself. If you write tools to find bugs, people always ask you if the tool finds bugs in itself. Well, FindBugs certainly does on a regular basis.

I analyzed Vuze (formerly Azureus), and the detector reported 35 warnings. Of those warnings, 17 appear to be legitimate issues, and another 17 are probably benign warnings that could be eliminated through the use of the JSR-305 @WillClose or @WillCloseWhenClosed annotations. (These annotations are used to specify methods and objects that assume responsibility for closing a resource.) 1 warning was essentially a duplicate of another (apparently correct) warning.

Analysis of jEdit was not quite as impressive, but still interesting: 4 apparent bugs, 9 warnings about probably-correct code that could be eliminated by annotations, and 3 cases where the analysis was wrong. (I need to investigate the last category.)

One type of false positive the paper didn't mention (that I can recall) was when one resource object "wraps" another. This, of course, is a common design pattern (Adapter) used in the java.io package.

Example:
InputStream in = new FileInputStream(filename);
Reader r = new InputStreamReader(in);
try {
...
r.read()
...
} finally {
r.close();
}
The analysis assumes that the InputStream is the obligation needing to be cleaned up, but the finally block closes the Reader instead.

The @WillCloseWhenClosed annotation would fix this problem (explicitly specifying the "transfer" of one obligation type to another), but since JSR-305 is not official yet, the standard Java classes don't use this annotation.

I worked around this issue by having the detector find likely places where an obligation transfer occurs, and then checking to see if the unmet obligation can be explained by an obligation transfer. This heuristic seems to work fairly well in practice.

Interestingly, a similar issue occurs when the "wrapped" resource is closed instead of the "wrapper". Technically, this could be considered a bug (the "wrapper" resource's close() method might have extra work it wants to do), but in many cases this is also a correct approach. The same heuristic (looking for probable obligation transfers) seems to be effective.

Thursday, July 17, 2008

Don't use the Intel CPU fan

I have built two systems using Intel socket 775 CPUs recently. Last summer, I built one using a Pentium Dual Core E2140 (1.6 GHz), which I use at school. This summer, I built one using a Pentium Dual Core E2220 (2.4 GHz), which I use at home.

Putting together the newer one, I managed to break off one of the "legs" of the stock Intel CPU fan. So, I bought a cheap third-party CPU fan at a local computer store. The older system I use at school has the stock Intel CPU fan installed.

Interestingly, my home machine runs much cooler than the system at school. Even under load, neither core gets above 45C, and each core idles around 30C.

The system at school idles around 45C, and reaches close to 60C under load, even though the CPU is running nearly 1 GHz more slowly than my home machine. Each machine has a cheapo ATX case with a case fan (in addition to the power supply fan.)

This strikes me as odd: if you follow Intel's installation instructions exactly, you get pretty inadequate cooling. I know the customer reviews on newegg always say that the Intel CPU fans suck. Well, I guess they do!

Monday, July 14, 2008

Obligation analysis

A common form of runtime error in Java programs is not closing or freeing an acquired resource on all paths out of a method. This kind of error is especially common with i/o streams, but also affects database resources, JSR-166 lock objects, etc.

FindBugs has a couple detectors that I wrote quite a while ago for detecting such errors. The detectors use a rather ad-hoc analysis, and produce a variety of annoying false positives.

Wes Weimer and George Necula proposed a nice static analysis to find such errors at OOPSLA 2004. I am finally getting around to getting this analysis implemented in FindBugs. Their analysis tracks obligations (open streams, db connections, etc.) on (effectively) all acyclic paths through methods, the basic idea being that every acyclic path ought to discharge all of its obligations. The analysis does not attempt to track the actual resource values through variables and heap locations. Instead, it just checks that each resource acquisition reaches an appropriate resource de-allocation.

I think I have finally gotten to the point where I understand how the analysis works, and the initial implementation in FindBugs seems to be working. I still need to complete the database of method calls which create or discharge obligations, and also implement several post-processing steps for false positive elimination, but I don't think this will be a huge amount of work.

Friday, July 11, 2008

Ruby on Rails in Netbeans

Netbeans is slowly becoming my favorite IDE. (Sorry, Eclipse!)

Today I started using the Ruby on Rails support within Netbeans, and it's quite nice. I'm probably not doing anything terribly sophisticated, but I did manage to create and run migrations, create some controllers and views, and launch the app, all from within Netbeans. Eclipse probably has support for all this stuff, but due to unexplained Eclipse crashes (on Linux), I can't actually use it.

I'm using the JRuby plugin for Netbeans, which means my rails code is actually running in Java. Kinda nice - Java is a more ubiquitous runtime environment that Ruby, so I'm thinking this will be helpful when it comes to deployment time.

Monday, June 9, 2008

Eclipse weirdness, NetBeans to the rescue

Last week, I did a hardware upgrade on my home PC. Originally, I had an EliteGroup 848P-A motherboard with a Pentium 4 2.8GHz (Prescott) with 2 GB of DDR 400 RAM. The new configuration has a Gigabyte GA-P35-S3G motherboard with a Pentium Dual Core E2220 (2.4GHz) and 4 GB of DDR2 800 RAM. It was a pretty cheap upgrade, and performance on compute-intensive tasks seems to be about 2x faster. Kubuntu 8.04 recognized all of the new hardware; no reconfiguration was necessary.

Weirdly, there is one important application that no longer works following the upgrade: Eclipse. I get repeated segfaults in libjvm.so. As far as I can tell, it's not a hardware problem. All other applications I have tried have been 100% stable, my CPU temperature has not exceeded 41 C for either core, memtest86+ did not find any problems with the memory, etc.

So, I conclude that it's some sort of software problem. Could it be a weird interaction between SWT and gtk+? This is where native code really sucks.

In the meantime, I'm using Netbeans for Java development. It's gotten quite a bit better since the last time I used it. It's maybe not quite as polished as Eclipse, but the important features (code completion, cross-referencing, and refactoring) are there.

Thursday, May 29, 2008

Summer!

Hooray, it's summer! (I define summer as the period of time between Spring and Fall semesters, not by the progress of the earth around the sun.)

I'm setting up my home machine to do some work on FindBugs over the summer, and since my Ubuntu 6.10 was getting a bit stale, I decided to upgrade. I happened to have a CD burned with Kubuntu 8.04, so I backed up my essential files and let the installer rip. So far, it seems nice. It took a bit of getting used to KDE rather than GNOME. Overall, KDE seems less polished than GNOME, but more configurable. I'm using Amarok to play my music files, and it appears to be significantly better than Rhythmbox. (See previous post to see my ranting about how much I dislike Rhythmbox.)

Out of curiosity, I installed the Ubuntu openjdk package, and tried running Eclipse on top of it. So far, it seems to work quite well! It's exciting to finally have a usable free Java implementation. Major kudos to Sun for open sourcing the JDK.

There is a weird bug on Ubuntu/Kubuntu 8.04 with Eclipse: here is the bug report. The workaround described in the bug report does seem to fix the problem.

I bought a new monitor, an Acer AL1916. Newegg was having a special for $159, with free shipping. Now (at long last) both of my monitors are the same size and resolution.

I finally started some work on FindBugs today. First project: implementing exclusive type qualifiers. (This is part of implementing support for JSR 305 type qualifiers in FindBugs.) Bill Pugh has a nice presentation about JSR 305 which explains all of the goodness.