Monday, February 17, 2014

Using PerfView to catch eaten .Net exceptions

Most of the time eaten exceptions are nightmares to debugging guys. Almost all the developers are taught that never eat any exception but still there are chances that they may eat the exception as a short cut to hide the issues in their code. An exception means something  happened wrong and there should be some actions  to be taken to resolve or to inform the caller about that error. We cannot continue the program execution same way as if, there was no exception. When the developers hide exceptions they can continue for short period of time but eventually the consumers, who calls their APIs will get wrong data back and their tracks will fail. Usually by that time the application might be in business testing or other final rounds of testing. In the worst case it might be reached production. At this time if something goes wrong it would be difficult to find out as the original error is hidden somewhere other than the place where the error is visible.

There are many ways to capture these exceptions.Here I am explaining one of those ways to find out eaten exceptions using a free Tool called PerfView from Microsoft. You may download the tool from Microsoft downloads. Its a standalone executable. Below are the steps

  1. Run the tool.
  2. Start collection.
  3. Analyse the .etl file which is generated.
Here I am explaining in more detailed way by taking a scenario.

Sample scenario / application


        private static void DivideWhichNeverFails(int n1,int n2)
        {
            int r = 0;
            try
            {
                r = n1 / n2;
            }
            catch (Exception ex) 
            { 
            }
            Console.WriteLine(r);
        }

I don't think the above code needs any kind of explanation. The developer cleverly written to escape from the error. The caller will get a zero even if his operation didn't carried out. Again, this will happen only in the projects where the developers are working like type writers who just produce lines of code and code review is not at all followed.

If such a code enters into the code base, it may survive the testing as long as there are no calls into this method with n2 as 0. But it may fail once its in production on the label of an inconsistent issue. When we need to deal with such issues in production, the first thing should be to check for eaten exceptions. Perfview is a gift here.

Starting PerfView and collecting.

Just run the PerfView.exe and select the Collect menu -> Run.It will show a popup which has boxes to fill our application name and the log file path. Thanks to .Net CLR team for instrumenting everything using ETW. The PerfView collects the data using ETW providers and the file extension is .etl. Make sure in the 'Advanced Options' section '.Net' is checked.  'Run Command' button will run the application. Execute the use case which is reported as error. Then close the application. The data collection phase is over.

Analyse the .etl file

Now we need to analyse the logs collected. In the main window of PerfView.exe there is a file browser.Point it to the .etl file which is created as part of the data collection. Double click on the etl file to expand it. Select the 'Events' node and open it by double click. Then filter the 'Event Types' using Exception to see all the exceptions. It will give us the list of exceptions happened during the run.

To see the call stack, expand the 'Exception Stacks' node of the etl file. It will open the call stacks for all the processes happened in the system during the collection. Find out our particular process and get the exception.

Using PerfView to find out eaten exceptions of ASP.Net web apps.

Here instead of running particular application, use the global collection method. To collect everything, select Collect menu-> Collect option.Set the data collection etl file and click the 'Start Collection' button. Then execute the failed test case. Stop the collection and start analysis in the same way did for windows application.

Happy debugging.

No comments: