Home > IIS Stories > .NET Debugging #2/3 – Checking ASPx Pages running in IIS Process

.NET Debugging #2/3 – Checking ASPx Pages running in IIS Process

Pre-readings :
ASP.NET Threads – Thread Parameters in IIS Worker Processes
.NET Debugging #1/3 – What are in a memory dump

A sample ASPX


If you understand what are in a memory dump, it is easy to guess that a memory dump can include the information of currently running ASP.NET pages. In a case of troubleshooting, simply having list of running aspx pages, can make a progress to identify a problem. For example, when an IIS worker process shows high CPU utilization, or unresponsive status(hang issue), you may want to know what’re going on in the worker process by collecting a memory dump, snapshot of the process.

In this blog post, we are going to run a long running application(named longtime.aspx), and collect a memory dump before completing the request, and then review the dump file to find the name of ASP.NET page that was running at that time.

Here’s a sample code(longtime.aspx) for this article,

<%@ Import Namespace="System.Threading" %>
    Response.Write (DateTime.Now)

    Response.Write("<br>20 seconds passed<br>")


As shown above, when a browser runs longtime.aspx, the page will be running for 20 seconds, and send a response with the time taken. you can copy & paste the above code, and save it as longtime.aspx for your test.


This time, let me run this longtime.aspx, and before passing 20 seconds, i’m going to collect a memory dump to check longtime.aspx in the memory dump file.

Post-Mortem Debugging


Just after running the longtime.aspx using a browser, open a task manager to collect a memory dump,


(FYI, i’m running this test under .NET Framework 2.0 / IIS8 / 64bit W3WP process, you may have a different result if one of above conditions is different.)


Now, I have a dump file at the path, I’m going to open the dump using Windows Debugger(WinDBG) 64bit tool.

Because we are using a dump file instead of attaching WinDBG to a live process, this is a post-mortem debugging process that can be useful for support engineers can’t access a production server, or can help remotely.

In the debugger, click file menu, and [symbol file path],


In the above screen, set the symbol path as follows,


And, check ‘Reload’, and click [ok] button.

Now, it’s ready to run debugger commands.

To load debugger extensions


Actually, we’re ready to start debugging already, if we don’t need any help from a debugger extension,


for example, I ran ‘~’ command to see list of threads briefly, or we can run ‘lm’ command to see list of modules loaded by the target process, as follows,


but in .NET debugging tasks, it’s always a good idea to use debugger extensions such as SOS, PSSCOR2. SOS is already in place in your system, and PSSCOR2 is available to download at http://download.microsoft.com (use search keyword of PSSCOR2). Once you download psscor2, locate the psscor2 pacakge in your debugger installation folder.

To load SOS extension, run ‘.loadby sos mscorwks’ as follows,


To check if SOS has loaded successfully, you can use ‘!help’ command to see avaiable commands provided by SOS extension.

If you failed to load SOS, mostly, it’s because the version of mscorwks.dll does not match yours in .NET framework installation folder. In this case, it’s required to prepare the exact mscorwks.dll from the target machine that you collected the dump file, or find a dll which has the same version. Or, if possible, open a dump file in the target machine using WinDBG. Anyway, fixing this problem can be a long story to be covered in this article.

In the output of !help command, there are many useful commands to perform .NET debugging for troubleshooting cases. This time, to check running aspx pages, i’m going to run ‘~*e!clrstack’ command to review all the managed stacks from the dump,


In the output of ‘~*e!clrstack’ command, one of call stack displays managed stack frame as shown below,


The aspx page (ASP.NET application name) is found at ASP.longtime_aspx, above the function of ‘System.Web…Execute().

It’s also possible to do this by checking an individual thread as follows,


. Run !threads command to find threadpool worker threads,
. Run ~22s (in this example) to switch to thread #22
. Run !clrstack command to see its managed call-stack. longtime.aspx is shown too.

By using PSSCOR2, it can make this easier,


. Run ‘.load psscor2\amd64\psscor2’ to load psscor2 extension (after loading SOS)
. Run ‘!aspxpages’ command to list ASPx pages in managed threads of W3WP process.
. You can find longtime.aspx (in ThreadID=22 for this example) as shown above


In Summary,

by using SOS, or PSSCOR2 – debugger extensions, we can check running ASP.NET applications in the worker process at the time when a dump file collected. To use this tips in any troubleshooting scenarioes, there are two very improtant things to take note,

. The timing when you captured the process memory dump
    – To let the memory dump includes the exact information of the problem

. To collect dump files in multiple times.
    – To avoid that any innocent ASP.NET applications can be suspected by mistake

In addition, checking name of applications can help you to troubleshoot an issue, but there’re much more things enable you to reseach various issues by using commands, provided by SOS & PSSCOR2. In WinDBG, ‘!help COMMAND’ can show you how to. I hope this article can be a quick and good start of developing .NET Debugging skills.

Categories: IIS Stories

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: