However, just to be thorough, check the dialog box type to make sure it's truly waiting on user input. To get to the fourth argument, you need to dump the raw stack starting at the Child Extended Base Pointer (ChildEBP) for the frame you want to examinein this case, dc 1bbe404. (For a refresher about stacks and frames, see "Your First IIS Crash," September 2001.) Type
dc 1bbe404
in the prompt window. Figure 8 shows the output of that command. Notice that the values in columns 2, 3, 4, and 5 of Figure 8 match the first four columns of
01bbe404 41288959 00000000 04a3a470 41292d40 USER32!
MessageBoxA+0x16
which is the MessageBoxA frame, but you get more information.
The next value after 41292d40 is the fourth argument. In this case, the argument is just the hexadecimal number 10 (00000010). By looking in winuser.h, you can see the flag mapping for this value from the list that Figure 9, page 4, shows. (For information about what winuser.h is and where you can get it, see the sidebar "What's Winuser.h?") Note two values in Figure 9one value is for MB_OK = 0, and the other value is for MB_ICONHAND = 10. These values tell you that the dialog box has an OK button and is displaying the Hand icon. This flag information tells us that the dialog box is waiting for input and is therefore the culprit.
The blocking dialog box problem doesn't come up that often, but it's a good example of how to dive into a dump file with no idea of a culprit and just look through the file for something out of place. Unfortunately, I can't tell you that every message box causes a hang. Some system message boxes might not require user interaction. Such message boxes most likely won't cause hangs. So, if you see a message box in a hang situation, you need to go through the steps I've presented to determine the exact problem. You might also want to enable the Allow service to interact with desktop setting in the World Wide Web Publishing Service Properties dialog box, which Figure 10 shows. This setting lets the dialog box appear to an administrator who's logged on to the server.
Follow Your Instincts
This month, I showed you two simple versions of hangs. Obviously, many more varied and complex hangs can occur. The key is to diagnose the symptoms fully. I recently received a call in which IIS was hanging as soon as it started. I saw only one connection ever being allowed, which seemed odd because, by default, the system had at least two Asynchronous Thread Queue (ATQ) threads to handle incoming requests. If the threads were blocked, IIS should have handled at least two requests. If the network were at fault, IIS should have handled 0. So, I got a dump of the process and found a call to MessageBoxA from custom code. When I asked the customer about the code, he said that the code was part of a high-priority Internet Server API (ISAPI) filter used to authenticate users. Therein was the problem: If the filter threw a dialog box on the first connection and all users were required to go through the filter, IIS would hang at one connection.
In another call I received recently, I saw a machine hanging with dozens of threads that had SockWaitForSingleObject near the top of the stack. I knew that SockWaitForSingleObject was an NT Synchronization object relating to Winsock (or TCP/IP) and told the customer to check the network for problems. In the server farm, the customer found a switch that was saturated with traffic every time the problem occurred. In this case, IIS was hung because of an external piece of hardware.
You can gather a lot of information from these logs by using common sense, following your hunches, and performing basic troubleshooting. Although there are logs that you can use to go right to a line of code and say "This statement is causing the problem," you don't always have to go to that level to get useful information.