Tracking down BadImageFormatException in C#

I know It’s been quite some time since my last post, but what can I say? I’ve been quite busy ūüôā Here¬†is the latest issue that I got stuck on for a few hours, and I thought I’d share what worked in the end.

I was working on a large C# project that had a lot of dependencies on native C++ DLLs in Visual Studio 2015. I had compiled all the 3rdparty dependencies to DLLs myself and had included them in the C# project. On my main development machine, everything was working fine, but I couldn’t get the project to work on another machine with a clean Windows 10 install. The project would compile fine but would fail to run with BadImageFormatException.

From prior experience, I knew this error had to do with a mismatch between dependency architectures somewhere (e.g. 32 bit binary is trying to load a 64 bit binary or vice versa). However, this time I was so sure that wasn’t the case because I had built almost all the DLL dependencies myself and I knew that everything was built in x64 mode. Also, it was working fine on my development machine.

After a few hours of frustration and using the Fuslogvw.exe¬†tool without obtaining much more insight about the problem, I decided to use Dependency Walker to see what’s happening. This great little tool did magic! I noticed that one of the dependencies that I hadn’t built myself was actually a 32-bit binary. The reason this was not causing an issue on my development machine was that as bad luck would have it, the 64-bit version of that dependency was in my PATH variable on that machine, so my C# project would load up the correct DLL. However, on other machines with a clean Windows installation, this wasn’t the case and because the only found binary was the 32-bit version, I would receive that dreaded BadImageFormatException.

CheckedListBox throws “Out of Memory Exception” When Adding New Items

I was using WinForm’s CheckedListBox control a few minutes ago and my application was crashing with an out of memory exception. This was happening on the line where new items were being added to the CheckedListBox. It did not make any sense at all, since I was only adding the second item to the control. Also, I was pretty sure¬†I wasn’t being even close to running out of memory! ūüėÄ

By some happy coincidence, I figured out what the problem was. Some of the items I was adding to the list would return null in their ToString() method. Turned out that was what was causing the exception. I simply made sure that ToString() would not return null values¬†and that solved the issue. .NET can sometimes be stupid ūüėÄ

I guess it is advisable to always write¬†the ToString() methods with a blank string as the starting point (eg. return "" + this.ID so that it wouldn’t break in case ID is null).

C/C++: Code Not Working under a Certain Build Configuration

If your C/C++ code works fine under a certain build configuration (eg. Release) but not under another (eg. Debug) or simply works fine when built with a certain compiler, it is a sign that the code is not robust and some small detail which depends on compiler optimization is producing undefined behavior.

For instance, my code was working fine under Linux (using G++) and also Visual C++ 2013 (using the Release) configuration, but was giving me a hard time under the “Debug” configuration in VC++. Turned out that the compiler optimization¬†under “Release” was preventing a destructor from being called. Since the destructor was never called, no memory leak was occurring. Building under “Debug” would have disabled that optimization and the code would have crashed with a memory leak error!

This just emphasizes how important it is to test the code thoroughly and detect those parts that could lead to undefined behavior.

Fix MATLAB Error: “dlopen: cannot load any more object with static TLS”

On Linux, you may occasionally encounter the error “dlopen: cannot load any more object with static TLS” in MATLAB. This is a known bug since way back!

To fix, create a file “startup.m” in the directory that you start MATLAB from with the following content:

I know! It’s ugly… But it works!!

EDIT:¬†Since it was not clear, the folder that you start MATLAB from is by default “~/Documents/MATLAB” under Linux. On Windows, that would be “Documents\MATLAB”.

NPP’s Convoluion with Border Control Only Partially Implemented

One thing I discovered yesterday is that the image convolution filters implemented in NPP (such as nppiFilterBorder_8u) are only partially implemented! These family of functions are asserted to provide border control for the convolution, thus serving as a robust alternative to the regular image convolution functions in NPP (such as nppiFilter_8u). The catch is that the border control is only partially working.

The documentation on these functions is scarce. These functions expect an argument of type NppiBorderType to define their border treatment. Possible options are:

 

My experiments showed that the only working option is NPP_BORDER_REPLICATE. Any other option would result in the NPPStatus  error code of -9999 (equivalent to NPP_NOT_SUPPORTED_MODE_ERROR, for which I have, again, not found any documentations).

Seeing as the performance of the border-controlled convolutions is inferior to the box filter function (using large mask sizes), my assumption is that the NPP_BORDER_REPLICATE uses the nppiCopyConstBorder_8u function to implement its border-control.

Possible options include implementing the border control manually, if behaviors other than replication are desired.

 

 

NPP’s Box Filter (nppiFilterBox) is Broken

Surprisingly, the box filter function (nppiFilterBox_8u) ¬†that is shipped with CUDA as a part of the NPP library is broken! It is the same function that is used in the “Box Filter with NPP” sample.

If you import this sample from the CUDA SDK and try it with masks of size 13 an above, the filter produces garbage output (tested with CUDA 6.5). At this point, I have no idea why this is happening or why such simple filter may not work for larger mask sizes. An alternative would be to use the convolution filters (such as nppiFilter_8u).

 

EDIT (12/5/2014): I reported this bug to NVIDIA and today I received an email indicating that this bugs was now fixed and the fixed version will be available in the next version of the CUDA toolkit.