2

我一直在使用PDH( Performance Data Handler) 来收集有关我的进程正在运行的机器的性能数据。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 进行编译。

4

0 回答 0