工作中遇到一个软件总是莫名的崩溃到nvwgf2umx.dll,网上都说是显卡驱动问题,但是更新了驱动依然有该问题,于是怀疑是不是系统资源耗尽了。
为了定位以上问题,是用CBrother写了一个脚本定时读取数据写进日志里,这样可以根据软件崩溃时间看看当时的系统资源情况,最后发现还真的是有内存和显存泄漏,可帮了我大忙了。
import lib/consoleprocess import lib/windows/winapi import CBCLib.code /*typedef struct _MEMORYSTATUSEX { DWORD dwLength; DWORD dwMemoryLoad; DWORDLONG ullTotalPhys; DWORDLONG ullAvailPhys; DWORDLONG ullTotalPageFile; DWORDLONG ullAvailPageFile; DWORDLONG ullTotalVirtual; DWORDLONG ullAvailVirtual; DWORDLONG ullAvailExtendedVirtual; } MEMORYSTATUSEX, *LPMEMORYSTATUSEX;*/ var MEMORYSTATUSEX = new CLibStruct("int","int","int64","int64","int64","int64","int64","int64","int64"); /** typedef struct _PDH_FMT_COUNTERVALUE { DWORD CStatus; union { LONG longValue; double doubleValue; LONGLONG largeValue; LPCSTR AnsiStringValue; LPCWSTR WideStringValue; }; } PDH_FMT_COUNTERVALUE, * PPDH_FMT_COUNTERVALUE; */ var PDH_FMT_COUNTERVALUE = new CLibStruct("int","double","double"); @logger function logger_config() { var fileLogger = new logger::LoggerOutputFile(null,"freeMemory","%Y-%m-%d"); var consoleLogger = new logger::LoggerOutputConsole(); logger::addLoggerOutput(fileLogger,"[%d] %m"); logger::addLoggerOutput(consoleLogger,"%m"); } var rootlogger = logger::getLogger(); function getGPUFreeMemory(console) { console.write("nvidia-smi --query-gpu=memory.free --format=csv "); } var g_CounteraValue = null; var g_Pdh_PdhOpenQuery_func = null; var g_Pdh_PdhAddCounter_func = null; var g_Pdh_PdhCollectQueryData_func = null; var g_Pdh_PdhGetFormattedCounterValue_func = null; var g_query = null; var g_counter = null; var pdhdll = new CLib("pdh.dll"); function getCpuUsageRate() { if (g_CounteraValue == null) { g_CounteraValue = new CLibStructData(PDH_FMT_COUNTERVALUE); g_CounteraValue.setInt(0,0); g_CounteraValue.setPointer(1,null); if(!pdhdll.load()) { print "pdh.dll load err!"; return; } g_Pdh_PdhOpenQuery_func = pdhdll.findFunc("PdhOpenQueryW","int","pointer","pointer","pointer"); g_Pdh_PdhAddCounter_func = pdhdll.findFunc("PdhAddCounterA","int","pointer","string","pointer","pointer"); g_Pdh_PdhCollectQueryData_func = pdhdll.findFunc("PdhCollectQueryData","int","pointer"); g_Pdh_PdhGetFormattedCounterValue_func = pdhdll.findFunc("PdhGetFormattedCounterValue","int","pointer","int","pointer","pointer"); var addr = new CLibPointer(); addr.malloc(8); var res = g_Pdh_PdhOpenQuery_func.callFunc(null,null,addr); g_query = addr.readPointer(); addr.free(); if(res == 0) { var addr = new CLibPointer(); addr.malloc(8); g_Pdh_PdhAddCounter_func.callFunc(g_query,"\Processor Information(_Total)\% Processor Utility",null,addr); g_counter = addr.readPointer(); addr.free(); } } var res = g_Pdh_PdhCollectQueryData_func.callFunc(g_query); if(res != 0) { return; } g_Pdh_PdhGetFormattedCounterValue_func.callFunc(g_counter,0x00000200,addr,g_CounteraValue.addr()); var rateCpu = g_CounteraValue.getDouble(1); rootlogger.info("cpu rate: " + rateCpu); } var g_kernel32_GlobalMemoryStatusEx_func = null; function getFreeMemory() { var structData = new CLibStructData(MEMORYSTATUSEX); structData.setInt(0,MEMORYSTATUSEX.size()); structData.setInt(1,0); structData.setInt64(2,0); structData.setInt64(3,0); structData.setInt64(4,0); structData.setInt64(5,0); structData.setInt64(6,0); structData.setInt64(7,0); structData.setInt64(8,0); if (g_kernel32_GlobalMemoryStatusEx_func == null) { var kernel32dll = new CLib("kernel32.dll"); if(!kernel32dll.load()) { print "kernel32.dll load err!"; return; } g_kernel32_GlobalMemoryStatusEx_func = kernel32dll.findFunc("GlobalMemoryStatusEx","int","pointer"); } var res = g_kernel32_GlobalMemoryStatusEx_func.callFunc(structData.addr()); var totalMem = structData.getInt64(2); var freeMem = structData.getInt64(3); rootlogger.info("memory: " + freeMem / 1024 + " KB / " + totalMem / 1024 + " KB"); } function main(parm) { var console = new ConsoleProcess(); console.start(); rootlogger.info("console pid:" + console.getChildPid()); var str = console.read(); rootlogger.info(str_convert(str,"ascii","utf-8")); getGPUFreeMemory(console); while(true) { var l = console.readLine(); if(l == null) { Sleep(1000 * 5); getFreeMemory(); getCpuUsageRate(); getGPUFreeMemory(console); continue; } if(strfind(l,">") == -1 && strfind(l,"--query-gpu") == -1) { rootlogger.info(str_convert(l,"ascii","utf-8")); } } console.closeProcess(); }
运行后会在脚本旁边写一个日志。出现问题直接在日志里查时间就行了。
有些电脑取显存这句命令行不行,"nvidia-smi --query-gpu=memory.free --format=csv",可以换一下两个试试:
"C:\Program Files\NVIDIA Corporation\NVSMI\nvidia-smi.exe --query-gpu=memory.free --format=csv"
或者
"C:\Windows\System32\nvidia-smi.exe --query-gpu=memory.free --format=csv"
取决于你nv驱动程序装在哪里