Monday, February 27, 2012

DotNet Watcher - To find out eaten exceptions at runtime

One of my current .Net projects, which started from the VB 6.0 days has lot many areas where exceptions are eaten using empty catch blocks. As the project is in Agile methodology where people give more importance to delivery than quality, we cannot blame developers for writing this type of code. On a build day, if the app shows an exception dialog, the best way they are finding is the empty try-catch block and handle the consequences as bugs.

When we went to MSFT for reviewing the app, this caused so many troubles and they introduced us to their internal tool which captures the eaten exceptions. That was really helpful for debugging the application in the production environment. There are so many tools available public to track the same but this tool is so simple and easy to use. I was really excited and wanted to blog about the same. But not sure whether there were any permission or other license-related issues as the tool is Microsoft internal.

Days were happy when we were on .Net 3.5. But when we migrated our project to .Net 4.0, the MSFT tool stopped its support. It was targeted to the .Net 2.0 base run time and we were forced to recompile against .Net 4.0. The process of reflecting on the tool and google started in parallel and the reflecting wins and we got the tool in 4.0. But the interesting thing I got during the google is a link to Mike Stall's .Net blog which explains the basics of that tool.Yes.I can blog about the tool as the details are already available to the public.

How the tool works

The tools work based on MDbgCore.dll1 engine provided by Microsoft. It can either start an application in the attached mode or attach itself to a running process. Then it hooks to the debug points and other operations that are happening on the target application. Once a hooked operation happens it passes the control to our debugger host application where we can print or log the details.

Coding a Debugging host 

From the programming aspect, things are more clear. You need to refer the MDbgCore.dll to your application. Then create an instance of MDbgEngine to start or attach to a process that will give you MDbgProcess instance. The processInstance.Go.WaitOne() will wait for the notification from the target application. Once a notification comes, it will be an instance of the BuiltInStopReason derived class.Handle that accordingly.
            MDbgEngine debugEngine = new MDbgEngine();

            if (int.TryParse(args[0], out processId))
            {
                proc = debugEngine.Attach(processId);
            }
            else
            {
                proc = debugEngine.CreateProcess(args[0], ""DebugModeFlag.Debug, null);
            }
            while (proc.IsAlive)
            {
                // Let the debuggee run and wait until it hits a debug event.
                ManualResetEvent handle = proc.Go() as ManualResetEvent;
                handle.WaitOne();
                object o = proc.StopReason;
                // Process is now stopped. proc.StopReason tells us why we stopped.
                // The process is also safe for inspection.            
                ExceptionThrownStopReason m = o as ExceptionThrownStopReason;
                if (m != null)
                {
                    ProcessException(m, proc, callback);
                    continue;
                }
            }

Note: Important thing here is you need to run this in a separate thread or use async delegate to avoid the application waiting endlessly.  This was not in the sample provided by Mike Stall :-).

Modifications I did

Mike Stall's blog explains the basics such as how to attach to the target application and print the exception. I took it a little further to have a UI around. Also planning to add more scenarios such as capturing when the classes are being loaded along with capturing eaten exceptions.

Intended audience

Mainly the developers who are coding in .Net for years but don't know how the .Net application works internally. Then the developers who are in the same state as mine where they had to deal with so many eaten exceptions. Finally, developers who are interested in writing their own debugging tools. I know there are so many apps available that do the same. But seems a little difficult to make suitable for our purpose.

Source code

As I am planning to add more features I am not attaching it with this blog post. You need to go codeplex for the sample ie the application named DotNet Watcher  GitHub for the application source code. This is my first published project in CodePlex.

1 Locate the dll at :\Program Files\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\MdbgCore.dll

1 comment:

Unknown said...
This comment has been removed by the author.