Analyzing HttpWebRequest Connection Saturation in .NET

WinDbg is a powerful tool and can use the SOS extension (that ships with the .NET framework) to look into and analyze Managed Code.Another powerful tool is Debug Diagnostics.It uses the same Debugger Engine that WinDbg uses and can run analysis scripts.You can use Debug Diagnostics and a custom script to analyze hangs and performance issues with the HttpWebRequest class.

I will walk you through some techniques that will allow you to customize your own Debug Diagnostics script to analyze .NET HttpWebRequest connection saturation.

The technique I will use is to:

1.Walk the threads in a Dump and look for Managed threads that have System.Net.HttpWebRequest.GetResponse on the stack.To me that means we are waiting on a response and may indicate an issue.

2.For each of the threads found above, I will get the ServicePoint object and see how many connections it allows vs.how many it currently has.

3.Make a suggestion on how to fix it!

DebugDiag (Debug Diagnostics) has a great help file and some starter scripts.I wanted to use jscript so the starter scripts did not do much for me since they were written in VBScript.I put all the metadata for the script on one line so that when I get script errors I can easily map this to the script I am editing in Visual Studio 2008.Save the script (with a .asp extension) to the Scripts sub-directory of where DebugDiag is installed and it will show up when you start DebugDiag.

The ManagedFieldOffsets function is pretty interesting.You could use several techniques in this script to get the information you want from a managed object.The SOS extension has a !do command that can dump the fields of an managed object and you can hunt through that for each object to get the value of a field you want, then !do that object etc… until you get to the value you want.However, I want this script to perform well, so I will use offsets from the object base address to get to the data I want.I could hard code these offsets, but if they change or I am using a different version of the CRL, I would have to change my script.So this handy function (actually used lick a class) is an expando based class that will store these offsets for me.

NOTE: If you want to learn about these commands, load a dump file with HttpWebRequest on the heap and play with each of the g_Debugger.Execute commands I am using!

I have included the completed script.It needs some error checking and polishing, but it will get the job done.It will report out any threads waiting on requests and dump out any HttpWebRequest objects that have ServicePoint objects with the CurrentConnections >= ConnectionLimit

Here is the complete code listing (save to the DebugDiag Scripts directory as WebRequestConnections.asp):

Manager.ReportError("The number connections exceeds the number of available connections for these threads:" + g_MaxConnectionErrorThreads.replace(/, +$/g, "") ,"Increase the number of connections available per this article: <a TARGET=_blank href='http://msdn.microsoft.com/en-us/library/7af54za5.aspx'>Managing Connections</a>");