工作中遇到一个软件总是莫名的崩溃到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驱动程序装在哪里