다음을 통해 공유


Lab 18: Debugging a handled and unhandled exception

This article has been moved to its new home here: https://benperk.github.io/msdn/2016/2016-IISLAB-lab-18-debugging-a-handled-and-unhandled-exception.html

In this lab you will use procdump to view exceptions and capture a memory dump when an exception happens.

Setup

  • Install Debugging Tools for Windows – For WinDbg
  • Install and Configure CSharpGuitarBugs on an IIS server as described in Lab 1
  • Place PROCDUMP executable on the IIS Server
  • Read this article here about the –f parameter

Lab 18.1 – Handled Exception

1. Access the CSharpGuitarBugs website so that a W3WP process has been instantized.

2. Open Task Manager and find the PID for the web site, something similar to that shown in Figure 1.

image

Figure 1, find the PID of a W3WP.exe process

3. Open a CMD prompt and navigate to the location where you copied procdump to.

4. Enter and execute the following command, as seen in Figure 2.

 
procdump -64 -e 1 -f "" 3660

image

Figure 2, execute procdump to watch for exceptions

5. While the command is running, click on the FAQ link in the Forums section, you should the exceptions, similar to that show in Figure 3.

image

Figure 3, execute procdump to watch for exceptions

6. Prepare procdump to capture a memory dump when the System.DivideByZeroException happens by executing this command, shown in Figure 4.

 
procdump -64 -e 1 -f "DivideByZero" 3660

image

Figure 4, execute procdump to capture a memory dump for a specific exception

7. Reproduce the exception by pressing F5 of navigating back to the main page and clicking on the FAQ link in the Forums section.  You should see something similar to that shown in Figure 5.

image

Figure 5, execute procdump to capture a memory dump for a specific exception, memory dump captures

8.  Open the memory dump in WinDbg and execute !mex.dae and !mex.clrstack2, note that in Figure 4, I incorrectly left out the –ma parameter which resulted in a mini memory dump being taken instead of a full dump.  Take another shot at capturing the memory dump, but this time include the –ma as seen below.

 
procdump -64 -ma -e 1 -f "DivideByZero" 3660

Compare the output of each of the dumps and compare the differences when you execute mex.dae (dump all exceptions), as seen fin Figure 6.

image

Figure 6, WinDbg dump all exceptions within a full memory dump

And the output of mex.clrstack2, as seen in Figure 7.

image

Figure 7, WinDbg clrstack within a full memory dump

You typically find the exception is thrown by the method at or near the top of the stack.  Give that exception and the method that triggers the exception to the developer who wrote the code and ask for it to be fixed!

Lab 18.2 – Unhandled Exception

1. Access the CSharpGuitarBugs website so that a W3WP process has been instantized.

2. Open Task Manager and find the PID for the web site, something similar to that shown in Figure 1.

3. Open a CMD prompt and navigate to the location where you copied procdump to.

4. Enter and execute the following command, as seen in Figure 8.

 
procdump -64 -e 1 -f "" 3660

image

Figure 8, execute procdump to watch for exceptions

5. After clicking the FAQ link from the main page, you again will see the DivideByZero exception, that was the handled exception which ran within a try{}…catch{} block.  This time, click on the “Report this Exception” button which will trigger an unhandled exception.  When testing this on an IIS server, you will get the YSOD (Yellow Screen of Death), as seen in Figure 9.

image

Figure 9, execute procdump to watch for exceptions

This is because it is being run on the server the customErrors is not Off.  To see how it would look in the live site, check it out here.  Not so intuitive huh?

6. Execute the following command to capture a memory dump when the unhandled exception is triggered.  It is the same as the handled one, so already be on the FAQ page before running the command.  Once you run the command, click on the “Report this exception”.  Also remember to include the –ma parameter so you get a full memory dump.  See Figure 10.

 
procdump -64 -ma -e 1 -f "DivideByZero" 3660

image

7. The capture of the unhandled exception, looks similar to the handled, Figure 11.

image

Figure 11, execute procdump to capture a memory dump for a specific exception, memory dump captures

8. Let’s open this memory dump in WinDbg and see what it looks like.  Execute !mex.dae and !mex.clrstack2 and see if there are any differences, see if you can view the code to determine for yourself the difference between a handled and unhandled exception, even though I already mentioned that previously.  Dump all exceptions is displayed in Figure 12.

image

Figure 12, WinDbg dump all exceptions within a full memory dump

9. No significant difference there, in Figure 12, let’s look at the mex.clrstack2 output, Figure 13.

image

Figure 13, WinDbg clrstack within a full memory dump

No difference there either, so apparently the stack and exception look the same using mex regardless of handled or unhandled.  However, how they look to the client consumer is very different.  You did get pretty far in finding what the reason for the exception is.  You can view the code here and see the difference between the FAQ() and the FAQ(string) method.