TN063: Debugging Internet Extension DLLs

If you have written an Internet Server extension DLL, you might be interested in getting it running under the debugger so you can trace its execution, set breakpoints, or monitor variable values after the extension is called. Getting the Microsoft Internet Information Server (IIS) up and running with your DLL in the debugger is a little tricky. You will need to first find a quiet server where you can debug your DLL in a controlled setting. Once you’ve found such a resource, you can start debugging your DLL.

Because of differences between version 3.0 and 4.0 of IIS, it is important to know which version you will be using to debug your DLL.

Debugging Using Internet Information Server (3.0 and earlier)

Follow these steps to debug an Internet Server extension DLL using IIS 3.0:

  1. Stop the IIS publishing services by using the IIS Manager, or by stopping the services with the Services icon in the Windows NT Advanced Server Control Panel. Note that you must stop all three services even though you are only debugging extensions to the World Wide Web publishing service. To make things easier, you might want to make the services "Manually" started in Control Panel so you can avoid this step later in your development.

  2. Start Microsoft Visual C++, and click the Close Workspace command on the File menu to close any opened workspace.

  3. On the File menu, click Open Workspace to open the INETINFO.EXE program. This file is in the directory where you installed the Microsoft Internet Information Server.

  4. On the Project menu, click Settings, then click the Debug tab in the Project Settings dialog box.

  5. With General selected in the Category box, type the following in the Program Arguments text box:

    -e W3Svc

  6. Choose Additional DLLs from the Category drop-down list. Then, in the Local Names box, specify the complete path and name of your extension DLL or DLLs. Make sure the check box next to each is marked.

  7. Click OK to close the Project Settings dialog box.

  8. Make sure that the .PDB file for your DLL is in the same directory as the DLLs you plan to debug.

Debugging Tips

The IIS can be run as an interactive application, making debugging much easier. To do this you need to make a few changes to your system. For the user account that you are going to run the server under, you need to add a few privileges.

To add privileges, run User Manager. (If you're using Windows NT 3.51, run MUSRMGR.EXE. If you're using Windows NT 4.0, run USRMGR.EXE.) Click User Rights from the Policies menu. Select the Show Advanced User Rights check box. Then select Act as part of the operating system from the drop-down list on the right, and add the user account.

Repeat this process with Generate Security Audits (also in the drop-down list on the right). Make sure that all Internet Services (WWW, ftp, and gopher) are stopped and INETINFO.EXE is not running (use TLIST to check). Log off and log back on. You can then load the IIS with the command line:

INetInfo.Exe -e W3Svc

To load IIS under a debugger (for example, under WinDbg), use the following command line:

WinDbg INetInfo.Exe -e W3Svc

You are ready to go. In Visual C++, point to Debug on the Build menu and then click Go. This action starts the WWW publishing service, and the debugger will be aware of symbols in your DLL. You can ignore the warning that the file doesn’t have debugging information.

When you close Visual C++, save the workspace for INETINFO.EXE. That way, you can avoid reentering the settings for the debugging session. Just open the INETINFO.MDS workspace file when you are ready to start the debugger again.

Cached DLLs

You can adjust the registry setting at HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/W3SVC/Parameters/CacheExtensions to have the server reinitialize DLLs each time they are used. If this setting is 1, the server will keep DLLs loaded in memory as long as possible. This is the default setting for the server, since it helps the server achieve peak performance, and should only be changed if you are using the server for debugging. If you make the setting 0, the server will always reload extension DLLs each time they are used.

Forcing the server to reload your DLL is helpful when your DLL might be crashing or upsetting any per-instance data that it maintains. By forcing the server to reinitialize the DLL, you can get your DLL back into a predictable state with little effort. Be sure to test your DLL using the normal CacheExtensions setting, however, to make sure code in your DLL isn’t completely dependent on that initial state.

Debugging Using Internet Information Server (4.0 and later)

There are several ways to establish an environment for debugging your server components and Internet Server extension DLLs when using IIS 4.0 or later. If you are using a debugger capable of attaching to a Windows NT process, you can use this functionality to debug your component or extension. For example, if you are debugging with Visual C++, take the following steps:

  1. Start the iisadmin process. This can be done from the command line with the command net start iisadmin. You can also use the Services dialog box from the Control Panel to start the IIS Admin Service, which will start iisadmin.

  2. Start Visual C++. Point to Start Debug on the Build menu and click Attach to Process.

  3. Select the Show System Process check box.

  4. Select the inetinfo process from the list and click OK.

  5. Start the w3svc service. This can be done from the command line with the command net start w3svc. You can also use the Services dialog box in the Control Panel to start the World Wide Web Publishing Service.

If the debugger you are using cannot attach to a Windows NT process, take the following steps to establish an appropriate debugging environment:

  1. Open the Services dialog box in the Control Panel.

  2. Select the IIS Admin service and click the Startup button.

  3. Select the Allow Service to Interact with Desktop check box and click OK.

  4. Repeat steps 2 and 3 for all processes that run under the IIS Admin process, for example World Wide Web Publishing Service and FTP Publishing Service.

  5. Use the Registry Editor (REGEDIT) to add a subkey named Inetinfo.Exe to the HKEY_LOCAL_MACHINE/Software/Microsoft/WindowsNT/CurrentVersion/Image File Execution Options key.

  6. Add the following entry to this new key:

    Debugger = <DebuggerExeName> where DebuggerExeName is the full path to the debugger you are using.

When the World Wide Web Publishing Service is started, your debugger will also be launched. You can now set appropriate breakpoints in your Internet Server extension DLL.

You won't be able to set breakpoints in a component's source code until the component has been loaded into memory. To do this, start Internet Explorer and view the .ASP page containing the object. As soon as the page is loaded, you should be able to set breakpoints in your component. Click Refresh to view the page again, and trigger the breakpoints you selected. If the component cannot be loaded even once (for instance, if the fault occurs in component startup code), you need to load the component DLL prior to starting the debugging session. (See step 11 below.)

In some cases, you may not be able to use either of the two procedures outlined above. If you have difficulty using either of these strategies, there is a third approach, which has been described in previous releases of IIS. This third approach requires the establishing of Windows NT security privileges as well as making changes to the registry. It will also disable your ability to run IIS as a service. This approach should only be used if the previous two strategies have failed.

  1. Use the User Manager for Domains administration tool (USRMGR) to add the Log on as Service, Act as part of the operating system, and Generate security audits rights on the local computer to the Windows NT account you will use when debugging the Internet Server extension DLL.

  2. Use the Distributed COM Configuration utility (DCOMCNFG) to change the identity of the IIS Admin Service to the user account you will use for debugging.

  3. Use the Registry Editor (REGEDIT) to remove the LocalService keyword from all IISADMIN-related subkeys under HKEY_CLASSES_ROOT/AppID. This keyword may be found in the following subkeys:

    {61738644-F196-11D0-9953-00C04FD919C1} // IIS WAMREG admin Service

    {9F0BD3A0-EC01-11D0-A6A0-00A0C922E752} // IIS Admin Crypto Extension

    {A9E69610-B80D-11D0-B9B9-00A0C922E750} // IISADMIN Service

    The LocalService keyword may be found in additional subkeys of AppID.

  4. Add LocalServer32 subkeys to all IISADMIN-related subkeys under the CLSID node of the registry. This will include subkeys corresponding to all of the subkeys you removed in the previous step. Set the default value of these new keys to <path>\inetinfo.exe -e w3svc. (<path> is normally "c:\winnt\system32\inetsrv".)

  5. Stop the WWW and FTP services from the Microsoft Management Console, or from the Services dialog box in the Control Panel.

  6. Start Visual C++ and select the Debug tab in the Project Settings dialog box.

  7. Type the following path in the Executable for debug session field:

    C:\WINNT\System32\Inetsrv\Inetinfo.exe

  8. Type the following in the Program Arguments field:

    -e w3svc

  9. Select the Link tab in the Project Settings dialog box.

  10. Enter the name and path of the Internet Server extension DLL you are debugging in the Output file name field.

  11. Optionally, add your component DLL to the list of Additional DLLs that are loaded before the application starts. This will allow you to set breakpoints in component startup code.

  12. Click the Go button to start the debugging session.

Note   After you have completed the debugging session, you must reverse steps 5 through 1 to restore the previous settings and allow IIS to run as a service.

Technical Notes by NumberTechnical Notes by Category