While writing my first real Ruby app using my bridge, I came across my first real honest-go-goodness nasty bug. Most of the other bugs have been nice and deterministic – something I just did caused the bridge to blow up. This one was just plain nasty, and of course it was based on an invalid assumption. It manifested itself as a corrupted call stack and dumped me rather unceramoniously into the debugger.

Here’s the invalid assumption: I thought that there wasn’t return-value covariance in C# (the CLR supports return-value covariance, but I thought this was a safe assumption since I figured most folks wouldn’t be writing code using ilasm).

For example, you cannot have these two methods in the same type:

int Method() and string Method()

However, if they can be distinguished based on their parameter lists, then it’s OK:

int Method(int) and string Method(string)

I had made the assumption in my overload shim that all overloads would return the same type. Oops. I ran into this bug when I was calling ToolStripItemCollection.Add.

What’s worse, the MSDN docs essentially imply that all of the return values are the same since the return values of the methods aren’t shown in the overloads list. I only noticed this when I pulled out Reflector to look at the methods myself.

I’m really happy that this was the root cause of the stack corruption bug. I was worried that there was something flaky about the interactions between the garbage collectors on both sides of the marshaling boundary …