ODP.NET application crash with DateTime parameters

I spent some time yesterday debugging a crashing console application – a proof of concept for a wrapper library I’m writing around an Oracle database. I had successfully read values from the DB – writing that code took all of five minutes – and then tried a MERGE statement.

(Side note: this is the first time I’ve written a merge statement. In fact, while I did know of MySQL’s “REPLACE INTO”, I had no idea that such a thing existed.)

I played around with the statement in TOAD for a while, to make sure it was correctly written, typed it into my editor, added parameter placeholders, added the arguments for the parameters and ran the application. It flashed on the screen and then disappeared.

Which was a bit weird, seeing as it ended with a Console.ReadLine() call. I re-ran the app just to make sure I didn’t accidentally press anything, and the same thing happened. Meanwhile, looking at the results on the TOAD side of things, the value was definitely updated.

I was a bit tired, so it took me a while to notice that the process exit code was 0x80000003 – nonzero, so some sort of error was being reported. Still, even asking the debugger to break on all Win32 errors yielded nothing. And between the statement being executed and the crash, ProcMon reported that all operations the application performed were successful.

I was too tired to make sense of it, so I went home and took a fresh set of eyes with me today. I began to narrow the issue down to a single parameter. At which point I began to get NRE’s instead of crashes. And the stack traces contained references to the special handling of DateTime parameters.

I was doing this:

command.Parameters.Add(new OracleParameter("curdate", DateTime.Now));

Figuring that DateTimes were a special case, I chose this constructor overload instead:

command.Parameters.Add(new OracleParameter("curdate", OracleDbType.Date,   DateTime.Now, ParameterDirection.Input));

After which I re-ran the app, and like magic, everything worked.

Now, realizing that Oracle has more than one way of representing the data contained in a System.DateTime, I understand how there might be a code path or two dedicated for the handling of DateTimes. What I don’t get is that it’s possible for the most common overload of the OracleParameter constructor to result in not an exception, but a full-on application crash.

Anyway, I hope this post saves someone else the trouble. Smile

Fixing broken tools

What sucks about open source is that when something breaks, there’s no guarantee that it will get fixed. What seriously rocks, though, is that you can do it yourself.

As an example of the latter, we’re using dotless for a project at work. I didn’t do much with it, apart from setting up the HttpHandler and letting our frontend developers loose on it. After a few days, though, they ran into an issue: editing an imported less file would not cause the root file to be evicted from the cache.

I figured this was an omission in the caching mechanism, and downloaded the sources from GitHub. When I finally got everything right so that debugging was an option, something weird happened – the path parsing seemed to break, and our includes no longer worked the way they used to.

I dove into the issue, thinking that I’d have to fix it in order to be able to debug the cache issue. When I finally understood enough of the codebase to write the correct tests and make them pass, I suddenly noticed that cache invalidation worked again.


Except, not so much when I finally figured it out. The path parsing bug led to imports like “/foo/bar” resolving to “foo/bar”. That in itself was bad enough, mind you, but since the cache code passed the same paths to the CacheDependency constructor, the net result was a cache dependency to a nonexistent file!

The docs for CacheDependency state the following:

“If the directory or file specified in the filename parameter is not found in the file system, it will be treated as missing. If the directory or file is missing when the object with the dependency is added to the Cache, the cached object will be removed from the Cache when the directory or file is created.”

That’s great, but in this particular case, I never want to watch for a file that might get created, so I would have been better served with an error. Smile

Anyway, after this little excursion in yak shaving it made sense that fixing path resolution also fixed the cache.

I contributed my changes as a fork on GitHub in the hopes that it will benefit others as well. Also, it would be nice if my changes were merged upstream, so I wouldn’t have to maintain my own fork. Smile with tongue out 

(I’m fairly sure I botched the Git operations somehow, though – I get that Git is awesome, but boy does it come with a learning curve.)

Anyhow, the important thing is that now our frontend developers don’t have to work with broken tools.