MORE INFORMATION
Background and Architecture
To help you understand why these problems occur and the steps to resolve
the problem, the overall architecture of the performance library is
described here.
Within Advapi32.dll, the performance library supplies the functionality
behind the RegQueryValueEx API with the HKEY_PERFORMANCE_DATA key. On
Windows NT, the performance data is collected at the time RegQueryValueEx
is called. It is not continuously stored in the registry.
Some performance data is collected within the performance library in
Advapi32.dll. Advapi32.dll uses internal functions to get data for system
objects, such as Memory and Process. The performance library collects other
data by calling DLLs, known as performance monitor extensions. The DLLs
export three functions (that is, the Open, Collect, and Close functions),
which the performance library uses to gather data from the extensions. See
the References section of this article for more information about adding
custom performance counters.
When an application queries for performance data, the library loads all
performance extension DLLs and calls the Open and Collect functions in a
loop. For the extension DLLs, which do not support the object index that is
being queried, the extension DLL indicates to the performance library that
it does not fill in any performance data in the data buffer. The following
sample code from the Collect function of a sample performance counter
extension illustrates this:
Sample Code
lpszNameTitleIndex = DataDefinition.ObjectType.ObjectNameTitleIndex;
if (dwQueryType == QUERY_ITEMS){
if (!(IsNumberInUnicodeList(lpszNameTitleIndex, lpValueName))) {
*lpcbTotalBytes = (DWORD) 0;
*lpNumObjectTypes = (DWORD) 0;
return ERROR_SUCCESS;
}
}
The performance library calls the Collect function for all extensions
within a try/except block so an unhandled Access Violation exception will
not be presented to the user if the DLL's Collect function executes code
that generates an exception. Instead an error is posted in the Windows NT
Event Log.
Troubleshooting Access Violations
If RegQueryValueEx presents an unhandled Access Violation exception in a
dialog box to the user, typically one of the performance extension DLLs is
the cause, not the caller of RegQueryValueEx. Because an extension's
Collect function is protected by structured exception handling in the
performance library, the fault occurs inside RegQueryValueEx but after the
Collect function has returned. Since all extensions get loaded regardless
of which counters are queried, the exception information does not indicate
which extension DLL caused the problem. Therefore, it is necessary to
enumerate the extensions and disable them. To get a list of the extensions
installed, use the Exctrlst.exe utility from the Windows NT Resource Kit.
This will display a list of all extensions by the service name and the name
of the extension DLL.
Following is a trial and error method that you can use to identify which
extension DLL is causing the problem. The performance library loads the
extension DLLs that are registered in:
HKEY_LOCAL_MACHINE
SYSTEM
CurrentControlSet
Services
<service name> (as indicated in EXCTRLST.EXE)
Performance
There is a registry value named Library that holds the name of the
extension DLL. For each performance extension, edit the Library name and
prefix it with an "x". By doing this, the performance library will
temporarily not load the extensions. Execute the code that calls
RegQueryValueEx again to verify that the exception does not occur. Although
unlikely, if the exception still occurs, then the problem is not related to
performance extensions. Otherwise, enable the performance libraries one at
a time by removing the "x" character from its registered library name and
then execute the code that calls RegQueryValueEx. After doing so (that is,
one extension at a time), it will identify the extension that is causing
the problem at the point the RegQueryValueEx causes an exception.
Additional Information and Comparing Installations
Use Tlist.exe in the Windows NT Resource Kit to get additional information
about the process. At the time the Access Violation error message is
presented, open a command prompt window and use the following tlist
command:
This command dumps out some memory usage information and lists all modules
loaded by the process. The list of DLLs includes the version stamp
information. Sometimes a problem occurs because a conflicting DLL version
is present. If the problem occurs on one machine, but not on another
machine then you can compare the output from both machines.
Depending on which extension is causing the problem, you may or may not be
able to debug the DLL further. If it belongs to another company, you may
want to contact that company to report the problem.
Troubleshooting Other Problems with Collecting Data
Another symptom of a problem that occurs when collecting performance data
is that the buffer returns without any data. Be sure to zero buffers before
the call to RegQueryValueEx to verify if this is the case. Typically, the
reason the buffer does not contain any data is that the Collect function
one of the extensions caused an exception, but it was handled by try/except
block implemented in the performance library.
The exception handler in the performance library will post an Event Log
message. Use Event Viewer to view the Application log to see event message
of source Perflib. If an exception occurred in the Collect function, an
event log message that has the following Event Detail dialog box
description will be posted:
The Collect Procedure for the <service name> service in DLL
<extension DLL name> generated an exception or returned an invalid
status. Performance data returned by counter DLL will not be
returned in Perf Data Block. Exception or status code returned is
DWORD 0.
And, the first DWORD in the data window of the Event Detail dialog box may
be 05 00 00 c0 (which is exception status 0xC0000005).
There may be other reasons why performance data is not returned.
Specifically, if the extension relies on a service to be installed and
running for it to gather the data, then performance data may not be
returned. This will not generate an exception, and it may not cause an
event log error to be posted. For example, the TCP counters. For more
information, query the Microsoft Knowledge Base with the following
keywords:
Getting More Information in the Event Log
The performance library reads a Windows NT registry value to select how
much information it will place in the Event Log. The REG_DWORD value named
EventLogLevel is placed in the following key:
HKEY_LOCAL_MACHINE
Software
Microsoft
Windows NT
CurrentVersion
Perflib
If you set the value to 1 the performance library will only post errors. A
value of 2 selects the posting of warnings and errors. A value of 3 selects
the posting of all success information as well as errors and warnings. A
value of 0 (default) posts no additional information. If you change this
registry value, stop and restart the process that reads the performance
data to see the change in event logging.