This tutorial describes how to detect deadlocks in an IIS ISAPI DLL.
This tutorial covers the following:
Related tutorials:
Detecting deadlocks in a child process.
Detecting deadlocks in a service.
Detecting deadlocks in a service child process.
Detecting deadlocks for a child process from the command line.
This tutorial applies to all native ISAPI DLLs and to mixed-mode ISAPI DLLs that uses the native Win32 services API.
Thread Validator ships with an example ISAPI DLL in the examples\isapiExample folder in the Thread Validator installation directory.
The ISAPI DLL has already been modified to use the NT Service API. In this tutorial we’ll describe the modification you would make to the ISAPI DLL to make it work correctly with Thread Validator.
The NT Service API is a simple API that allows you to load the Thread Validator profiling DLL and start the process of detecting deadlocks.
The API also includes some debugging functions to help provide debugging information via log files (the only way to get data out of an ISAPI DLL without a connection to the Thread Validator user interface).
The purpose of attachToThreadValidator() is to use the NT Service API to instrument the ISAPI DLL with Thread Validator.
// code to load Thread Validator into the IIS process for this ISAPI
// this assumes the ISAPI is in C:\testISAPIWebsite\
#include "..\..\svlTVStubService\svlTVStubService.h"
#include "..\..\..\svlCommon\svlServiceError.h"
static void attachToThreadValidator()
{
svlTVStub_setLogFileName(L"C:\\testISAPIWebsite\\svl_TV_log.txt");
svlTVStub_deleteLogFile();
SVL_SERVICE_ERROR errCode;
#ifdef IS6432
// x86 with x64 GUI
errCode = svlTVStub_LoadThreadValidator6432();
#else //#ifdef IS6432
// x86 with x86 GUI
// x64 with x64 GUI
errCode = svlTVStub_LoadThreadValidator();
#endif //#ifdef IS6432
if (errCode != SVL_OK)
{
DWORD lastError;
lastError = GetLastError();
svlTVStub_writeToLogFileW(L"Thread Validator load failed. \r\n");
svlTVStub_writeToLogFileLastError(lastError);
svlTVStub_writeToLogFile(errCode);
svlTVStub_dumpPathToLogFile();
}
else
{
svlTVStub_writeToLogFileW(L"Thread Validator load success. \r\n");
errCode = svlTVStub_StartThreadValidatorForIIS();
if (errCode != SVL_OK)
{
DWORD lastError;
lastError = GetLastError();
svlTVStub_writeToLogFileW(L"Starting Thread Validator failed. \r\n");
svlTVStub_writeToLogFileLastError(lastError);
svlTVStub_writeToLogFile(errCode);
}
svlTVStub_writeToLogFileW(L"Finished starting Thread Validator\r\n");
}
}
Now that the NT Service API has been implemented in your service, we can start collecting memory allocation data from the service.
If errors are found you will be presented with a dialog box specific to the error so that you can correct the error before starting the web browser.
To finish detecting deadlocks, you need to stop IIS.
If you had selected Stop IIS when web browser is closed on the Monitor IIS and ISAPI dialog then you have nothing to do.
Otherwise, choose Launch > Services > Stop IIS
Thread Validator will continue monitoring deadlocks during the service shutdown procedure and then present you with the deadlocks and threading report.
There are a few things to check.
svlTVStub_setLogFileName(SZLOGFILENAME);
You have learned how to add the NT Service API to an ISAPI DLL, how to use Thread Validator to monitor ISS and ISAPI, and what to look at to diagnose errors if things don’t work first time.