一直用Qt Creator开发Qt程序,Nokia的Qt Creator实在太慢了,启动慢,编译速度也是超级慢。昨天,终于它慢的让我无法忍受了,我决定抛开手上的一切工作,深入挖掘Qt Creator启动慢的原因。首先,怀疑是给力的Mcafee企业版卡住程序了。试试把Mcafee的一切监控都关闭,没效果!然后怀疑系统进程太多了,卸载掉SONY送的一堆无用程序,没效果!继续怀疑某些进程与Qt Creator有冲突(Windows7 x64嘛),kill掉所有无关进程,没效果!重置Windows的系统服务,没效果!我擦,人品差,Qt Creator与Win7 x64不兼容,我的出了这么个结论。连更改程序兼容性设置都不行?!
正当拿它没辙时,同学说它电脑上的Qt Creator跑的很欢很开心,也是Win7 x64。太打击了,都是Win7 x64,为何我这跑龟速?算了,身为软件开发人员,还是专业点吧,祭出Process Monitor,我偷窥它!呃……x64系统下跑32位程序,一大坨的Wow的dll调用要看吐。
但是,记录中一连片的Process Profiling操作耗时很久,1个耗时1秒钟左右。那Process Profiling是啥呢?后来,查了许多资料,发现它只是当程序空闲时Windows方便统计CPU使用率等性能信息插入的探测操作。也就是说,这么大会儿,Qt Creator啥都没干?!上面有个Qmake.exe的调用操作,难道启动慢跟它有关?找到了Qmake.exe,拿鼠标敲它两下,果然一个黑框卡住不动。搞半天,发现Qt Creator启动慢确实与Qmake启动慢有关,但也不全怨Qmake,Creator自己也有问题!
哎,瞅着一大片的Process Profiling没辙,谁让我软件调试没学好呢。WinDbg不会用呀,就是会用还得弄pdb,弄pdb还得重新编译Qmake和Qt Creator……无意间,禁用网卡试试,一下把所有网卡全部禁用。Qmake和Qt Creator居然奇迹般的启动飞快!这样行?!那我拿墙堵这俩进程不就好了!打开落灰的Windows自带防火墙,在高级规则里禁止Qmake和Qt Creator如站/出站。居然不行!也许这俩程序启动时在等个什么结果……能等啥呢?解决网络问题,当然还是要抓包,祭出Wireshark来抓包,居然是这样:
NBNS是NetBIOS Name Service的缩写,貌似Qt Creator在启动时查询CMAKE/CMAKE.EXE/SH.EXE这样的主机名?!这行为太匪夷所思了,还是得找源码看看:
#ifdef Q_OS_WIN
static QStringList detectShellPath()
{
QStringList paths;
QString path = qgetenv("PATH");
QStringList pathlist = path.toLower().split(";");
for (int i = 0; i < pathlist.count(); i++) {
QString maybeSh = pathlist.at(i) + "/sh.exe";
if (QFile::exists(maybeSh)) {
paths.append(maybeSh);
}
}
return paths;
}
#endif
这是Qmake的一段代码,它在启动时获取名为“PATH”的环境变量,然后用“;”拆开成为一个QStringList,最后把PATH环境变量中的每个路径都连接“/sh.exe”成为新路径,用QFile查找该路径是否存在。这样的的话,怎会产生查询SH.EXE主机名的操作呢?回过头来,在Qmake启动的Process Monitor监控记录中找到如下的操作:
居然用CreateFile打开\\sh.exe\,查一下MSDN,CreateFile是这么理解这种写法的:\\servername\pipe\pipename。CreateFile居然真的把sh.exe当作服务器名,来创建一个管道-_-!那这个“\\sh.exe\”是哪来的呢?由上面的代码,它是从环境变量拼出来的。我看一眼我的PATH环境变量,一下震惊了!!!里面一段是这样写的“;C:\Program Files\WIDCOMM\Bluetooth Software\syswow64;\;”。这个该死的反斜杠是啥时候弄出来的!去掉反斜杠,再次启动Qmake和Qt Creator,它俩终于像在我同学电脑上那样跑的很欢很开心了!
总结:看似系统问题,实则程序问题;看似程序问题,实则网络问题;看似网络问题,实则环境变量问题!如果Windows防火墙真的能把创建远程管道操作堵住的话,也许我永远找不到问题的真相。问题的根源和表象差的好远呀!