Saturday, January 19, 2008

Unmanaged Debugging Option Very Useful in Visual Studio .NET


When developing managed code that is interacting with unmanaged world one has to be very careful, especially when working with unmanaged memory.

Here's an example how critical memory bug can be omitted.

I was developing code that used Marshal.AllocHGlobal method to allocate unmanaged memory. Naturally I was freeing that memory after usage.

The code looked like
IntPtr unmanagedMemory = IntPtr.Zero;
try
{
unmanagedMemory = Marshal.AllocaHGlobal(nBytes);
//invoking unmanaged method here via P/Invoke
}
finally
{
Marshal.FreeHGlobal(unmanagedMemory);
}

Everything was okay; application was working perfectly, except occasional crashes with AccessViolationException. Exception of this type can happen when something is writing into wrong memory offset and system reacts by throwing an exception.

Exception wasn't thrown every time application was running and it was hard to detect what was causing it. At the top of callstack was ntdll.dll module.

I decided to turn on unmanaged debugging and see what is happening under the hood in the unmanaged world.
(To turn unmanaged debugging in Visual Studio you need to go to Project Properties -> Debug -> Check "enable unmanaged code debugging").

After turning on unmanaged debugging I've got an exception immediately.


Marshal.FreeHGlobal(unmanagedMemory) was throwing exception saying that there was heap corruption. This exception was repeating constantly.

Finally, the bug was found - unmanaged function was not behaving well with the pointer passed to it.

Every time you're developing managed code that is interacting with unmanaged memory it is highly desirable to turn on unmanaged debugging. This will save a lot of time when tracking memory related issues and exceptions. Also a lot of information about debugging .NET applications can be found in .NET Debugging

1 comment: