resize wtf

I get amused whenever I see another open-coded version of this in our codebase, a method for determining the resolution of a scaled-down image while maintaining aspect ratio:


while (x > targetx || y > targety) {
x *= 0.99;
y *= 0.99;
}

It’s pretty easy to discern that it will take a lot of iterations to accomplish this task. In fact I put it around 250 * log (x/x') where x’ is the target width. That’s maybe as many as 2000 FP multiplies depending on the difference in sizes between source and target image.

I guess computing the smallest scale factor and using it once was just too hard…

Meh

I’m playing with date conversions today, and again I’m struck by how much the Java Calendar should be held up as an example of the over-engineered API. Has anyone ever used anything besides the Gregorian calendar? They were so proud of it when it hit 1.1.

I should have two patches hitting kernel 2.6.26, one entirely cosmetic and one that fixes a real bug on Atheros wireless cards. Akpm did pick up the OMFS patchset so hopefully that will go in .27 timeframe, though the jury is still out on whether it hits mainline.

In other news, take that, Skype!

javac sucks

More evidence that javac is one of the dumbest compilers ever:

public class Foo extends java.lang.Object{
public Foo();
Code:
0:   aload_0
1:   invokespecial   #1; //Method java/lang/Object."":()V
4:   return

public static void main(java.lang.String[]);
Code:
0:   aconst_null
1:   instanceof      #2; //class Foo
4:   ifeq    15
7:   getstatic       #3; //Field java/lang/System.out:Ljava/io/PrintStream;
10:  ldc     #4; //String never!
12:  invokevirtual   #5; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
15:  return
}


Ok, I’ll give them a break — this probably never comes up in a real application.

Brute force ftw

I write dumb scripts with git! Here’s how to (slowly / automatically) remove any @SuppressWarnings annotations that don’t do anything:

for i in `grep -rl @SuppressWarnings src` ; do
echo $i
cp $i $i.tmp
grep -v "@SuppressWarnings" $i.tmp > $i
rm $i.tmp
git-commit -a -m "Disable warning suppressions for $i"
ant compile > build.txt

res=`grep "[javac].*error" build.txt || 
grep "[javac].*warning" build.txt`

if [[ ! -z $res ]]; then
echo error!
git-reset --hard HEAD~1
fi
done

Why I hate ant


$ strace -f ant > out.txt 2>&1
$ grep "stat.*java" out.txt | wc -l
32933

WTF? No wonder our build times suck. I still have yet to hear a rationale for the existence of ant that had any more substance than “but make uses tabs!”

Scripted

A month or two ago I was thinking about test-driven development and what a pain it is to write test cases. Or, well, test at all for that matter. Who needs testing when you have users to do that for you?

At work we have this fairly complicated UI that eventually interacts with stateless session beans in the whole wizbang J2EE world. Usually, I spend most of my debugging time tickling the backend rather than fooling with the UI so all tasks of logging in, navigating windows, setting up data and so forth are just overhead.

One previous company I worked at had an excellent solution to automating all of that without winrunner or other similar crap: everything in the GUI created a command string that was then fed to a command parser to perform the task. You could use these command strings exactly as a script to control the app. Had a crash? Just replay the customer’s log to see the segfault.

So I had the rather obvious idea: use an EJB 3 interceptor with XStream to record method calls, their parameters and return values to the server logs. Later, we can execute these logs to replay all the SLSB calls and check the return values. Ta-da, we have some automated tests without even trying. Not full coverage of course, but better than nothing at all.

Another developer got the lucky task of implementing it, but I’ve just started using it today. Very slick. Now we just need a Lisp interpreter and an email client.

mmio trace for fun and no-profit

I’m not sure what got me interested in assembly language as a nerdy high-schooler. It could have been the growing interest in computer graphics, at a time when you had to use assembly to get decent performance out of the machine. I remember learning tricks from much smarter people than myself, such as how to set a 256×256 pixel video mode so that you could address any pixel without ever needing to multiply. Not that you would use a multiply anyway since you can always use shifts and adds.

I suspect, however, that part of what spurred me on was an interest in reverse-engineering, specifically to crack games. You would start BattleChess, say, and it would ask you for some move from some historical chess game in a big book before letting you play. This was to ensure that if you copied the game, that you at least also photocopied your friend’s manual. [For the record, while I cracked a few games, I never released any such cracks. More from being l4m3 than any teenage sense of ethics. I did, however, release instructions for patching the video game “Home Alone” so that you could never die. I may have been the only person on the planet to play that one all the way through.]

In order to crack a game, first you would load up SoftICE, a killer software debugger that would let you debug almost anything. It would let you set breakpoints on interrupts so step one was to put a breakpoint on ‘int 10h’. Interrupt 0x10 was a call into the video BIOS for setting up the video card. Back in the DOS days, it was the first thing every graphical program (and therefore game) did, because you started out in text mode and had to go into VGA mode. The BIOS would know how to load all the registers for that particular card; you just had to say “put me in 320×200 mode, now, thanks!” and that was via the assembly command “int 10h”.

After SoftICE caught the interrupt, the screen would switch back from VGA mode into a text mode listing of assembly instructions and raw machine code hex values. I don’t think I knew what all these meant at first, but I understood ‘call’ and ‘jmp’, and everything else I quickly learned from a text file describing the x86 instruction set architecture. So cracking then became a matter of just single stepping through all of these instructions, and waiting for BattleChess to get to the part where it asks you the question. Then, you start paying attention, looking for the assembly equivalent of “Is the answer right? If so, goto game! Else goto nasty message!” Some of these were harder than others, but generally it looked something like:

mov ax, ds:[43ac]
mov cx, ds:[3401]
cmp ax, cx
jnz 0027

You could step through it, type the wrong answer, then watch it jump to instruction number 27 which then printed out the nasty message. Then you could try again, and this time modify the code while you’re in the debugger. For example, change the jnz 0027 to a few no-ops (instructions that do nothing). Type in the wrong answer, and now it keeps on going to the game. Bingo, the game is cracked! SoftICE was such a nice debugger that I even used it for C debugging until I finally moved off of that whole DOS thing.

Anyway, I’ll never be a Jon Johansen, but that interest in reversing stuff has stuck with me. I think that figuring out how the Karma worked, which involved many hours of pouring over hex dumps trying to come up with the pattern, was much more fun than coding the driver. Particularly when the “ah-hah!” moments would strike. Incidentally, coding the driver was/is still fun, probably more so than actually using the device.

This little walk down memory lane was inspired by the recent entrance of mmio-trace into my zone of consciousness. I’m not sure who used this first, but the Nouveau project has been using the utility for some time to reverse-engineer the NVidia video cards so that Linux can gain decent open source drivers. My laptop luckily has an Intel based video card, but it does have an Atheros wireless chip which also has a binary blob. There’s currently an effort to produce a reverse-engineered driver for it as well. In my case, the new driver almost worked, but I needed to come up with some other details, so I tried out mmio-trace.

PCI cards are configured by register writes, but the driver generally has to program it to get it going. The BIOS can’t do that work for us any more. So the OS maps a region of memory that the driver can just write into, which then all gets converted magically into writes into the PCI device’s register file. Thus, MMIO=”Memory Mapped IO”, and mmio-trace does what it sounds like. Using it is rather painless, you first ‘hook’ a module you want to capture, modprobe mmiotrace, then load the hooked module. All writes to PCI config space get captured into a debugfs file that you then run through a user-space filter. The end result is a nice report of all of the reads and writes to the registers of the PCI device. Very neat!

Oh, the driver maintainer already knew about the issue and confirmed my proposed change so hopefully by 2.6.26 ath5k will support my Macbook.

I hate you, Sun.

Is it too much to ask of a compiler that if it decides to blare warnings at you for no reason at all, that you can turn the !@#$ thing off? In a move that rivals the stupidity of certain gcc warnings, we have this:

[javac] file: java:519: warning: com.sun.rowset.CachedRowSetImpl is Sun proprietary API and may be removed in a future release

Well, hey that’s a nice heads-up to give me 600 times when compiling our tree. Let me go find the non-com.sun equivalent of that. Oh wait, there isn’t one! And, the freaking javadoc even tells you to do it that way. Okay, well, maybe @SuppressWarnings({"deprecation"}) will work? Nope, haha! Sigh. Time for a wrapper script.

Request of persons who wish to write a better javac: can I have plugins that let me muck with the AST? Custom static checking would be nice…

I’m a slacker

I was thumbing through Joel Spolsky’s new book on hiring talented programmers at the bookstore the other day. He asserts in the first chapters that great programmers are ten times more productive than bad ones. Could that be true? I played around with git today to generate statistics to see how it looks on our refactoring project this year:

user    commits   files changed  LOC added  LOC deleted         
dev0:       453            4258     +81538      -100344
dev1:       152            2297     +54462       -45343
dev2:       104             550     +24779       -17475
dev3:        82             250      +6465        -7852
dev4:        73             209      +3920        -2782
dev5:        56             208      +5158       -10049
dev6:        24             116      +3297        -7823

Wow. Of course KLOC isn’t everything, but take it on faith that dev4 causes more problems than he solves (dev5,6 were only on the project a short time), and that dev0 is the most awesome programmer that writes on this blog. And I thought surfing the web 7 hours a day was too much…