我一直在使用PDH
(Performance Data Handler
)收集有关我的进程正在运行的机器的perfmon数据。我对PDH
个对象Processor Information
和Memory
没有遇到任何问题,但当我尝试使用PhysicalDisk
我的程序挂起时。
我将代码缩减到了这个测试用例。
void
third()
{
char path[ PDH_MAX_COUNTER_PATH ];
DWORD size = 0;
PDH_STATUS status;
strcpy( path, "\\PhysicalDisk(1 E:)\\% Disk Time" );
// hangs
status = PdhExpandWildCardPath( NULL, path, 0, & size, PDH_NOEXPANDCOUNTERS );
HANDLE query;
PDH_HCOUNTER hCounter;
status = PdhOpenQuery( NULL, 0, & query );
// hangs
status = PdhAddCounter( query, path, 0, & hCounter );
}
当我自己运行此代码时,它工作正常。当我在我的大型程序中运行它时,它会挂起但仅适用于PhysicalDisk
。我的大型程序监控了十几个PDH
计数器,没有任何问题,但是当我添加任何PhysicalDisk
计数器时,它会挂起。计数器在数组中定义,因此所有计数器的代码都相同。
当它挂起时,这是堆栈后退跟踪
ntdll.dll!_ZwDelayExecution@8() + 0x15 bytes
ntdll.dll!_ZwDelayExecution@8() + 0x15 bytes
KernelBase.dll!_Sleep@4() + 0xf bytes
perfdisk.dll!_OpenDiskObject@4() + 0x105 bytes
advapi32.dll!_OpenExtObjectLibrary@4() + 0x1f9 bytes
advapi32.dll!_QueryExtensibleData@4() - 0x250f bytes
advapi32.dll!_PerfRegQueryValue@28() + 0x26d bytes
kernel32.dll!_LocalBaseRegQueryValue@24() + 0x2754e bytes
kernel32.dll!_RegQueryValueExW@24() + 0xae bytes
pdh.dll!_GetSystemPerfData@16() + 0x92 bytes
pdh.dll!_GetObjectId@12() + 0xdb bytes
pdh.dll!_PdhiExpandWildcardPath@24() + 0x38b bytes
pdh.dll!_PdhExpandWildCardPathHA@20() + 0xcb bytes
pdh.dll!_PdhExpandWildCardPathA@20() + 0x10a bytes
> dbb30.dll!third() Line 2472 + 0x16 bytes C++
dbb30.dll!dbbProfileReport::dbbProfileReport() Line 2490 C++
dbb30.dll!`dynamic initializer for 'dbbProfileReportObject''() Line 2367 + 0xd bytes C++
msvcr90d.dll!_initterm(void (void)* * pfbegin=0x0121d380, void (void)* * pfend=0x0121fddc) Line 903 C
dbb30.dll!_CRT_INIT(void * hDllHandle=0x00ae0000, unsigned long dwReason=1, void * lpreserved=0x0018fd24) Line 318 + 0xf bytes C
dbb30.dll!__DllMainCRTStartup(void * hDllHandle=0x00ae0000, unsigned long dwReason=1, void * lpreserved=0x0018fd24) Line 540 + 0x11 bytes C
dbb30.dll!_DllMainCRTStartup(void * hDllHandle=0x00ae0000, unsigned long dwReason=1, void * lpreserved=0x0018fd24) Line 510 + 0x11 bytes C
ntdll.dll!_LdrpCallInitRoutine@16() + 0x14 bytes
ntdll.dll!_LdrpRunInitializeRoutines@4() - 0x352 bytes
ntdll.dll!_LdrpInitializeProcess@8() - 0x765 bytes
ntdll.dll!__LdrpInitialize@8() + 0xb4f9 bytes
ntdll.dll!_LdrInitializeThunk@8() + 0x10 bytes
PDH
代码在我的进程中启动了6个线程,其中一个在function _PerfdiskPnpNotification
中,似乎是相关的。当我查看汇编代码时,主线程正在等待第二个线程设置标志。
我尝试使用管理员权限运行,但没有更改。谷歌搜索_ PerfdiskPnpNotification
发现它有时会尝试打开一个弹出窗口。我尝试从GUI应用程序运行更大的代码,但它也挂起了。我在两台机器(都是Windows 7)上尝试了更大的代码,但没有运气。较大的程序从全局对象的构造函数中调用PDH
代码,我尝试了来自全局的ctor的小测试用例,但它起作用了。
我尝试lodctr /r
来重建注册表,但没有快乐。
使用MSVC 2005和MSVC 2008 Express进行编译。