创造101肖战魏大勋是哪期 百度云管家是否跟百度全家桶系列一样呢

2019-11-04 20:05:18

转载,转载,转载!原作者:张银奎原地址:在调试器里看百度云管家著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。—————————最初我发现这个管家特别忙碌,即使当我根本没有使用百度云。更让我跌破眼镜的是,即使我把网线拔掉、关闭无线,它依然忙碌。这些反常的表现让我不得不留意它了。(图1任务管理器中缺页异常排名第一)起初是在任务管理器中发现百度云管家(以下简称其“管家程序”)很忙。图1是我某次看见它忙时做的截图。在这个截图中,系统中一共运行了175个进程,任务列表是按缺页异常总数(PageFaults)排名,管家程序排名第一位,而且遥遥领先,把一向排名靠前的McAfee安全软件(第二名和第三名)远远抛在后头(相差一个数量级)。顺便说下,排在第4位的BaiduProtect是管家程序的同门兄弟,以后台服务方式运行,权限更高。在PageFaults右侧的那一列是PFDelta,代表最近一秒钟新增的缺页异常个数,管家程序新增4千多个,但这并不是我看到的最高值,有时是7000多。再往右的一列是CPU净时间,即CPU执行管家程序的累计时间,14分37秒。这个数值也算较高了,因为系统中CPU频率高达2.6GHz,速度很快,排在后面的很多程序(图1中未显示出)的累计时间还不到1秒。排在第二名的安全软件CPU累计时间是1小时55分42秒,比管家程序还高很多。如果把缺页异常总数除以CPU净时间,便得到缺页异常与CPU净时间的比率。这个比率反应了CPU执行程序时触发缺页异常的频繁程度,不妨将其称为缺页异常净频率。为排名前两位的两个程序计算这个指标,其结果如下:0:000>??215415833/(14*60+37)int0n2456280:000>??34064443/(115*60+42)int0n4907可以看出管家程序触发缺页异常的净频率高得惊人,达到24万多次。这意味着CPU平均执行这个程序1秒钟就触发24万多个缺页异常。这也意味着,CPU花在这个程序上的时间有很多都用在了处理缺页异常上。(图2用ProcessExplorer观察线程信息)图2是使用MarkRussinovich先生的ProcessExplorer来观察管家程序的截图,显示的是管家程序的线程信息。可以看到,管家程序有四个很活跃的线程,它们的CPU占用率都超过了0.1%。图2中第1列是线程ID,第2列是CPU占用率,第3列是CyclesDelta,即最近一秒钟CPU执行这个线程所用的时钟个数。从WindowsVista开始,NT内核会读取现代处理器的性能计数器来统计CPU花在每个线程上的时钟个数。根据图2,最近1秒里,管家程序的前4个线程使用的CPU时钟数分别为1千4百万、1千5百万、3千2百万和1亿零5百万。图2下方是排名第一的8864号线程的更多数据,其中的Kernel和User分别是内核态净时间(23秒多)和用户态净时间(1分23秒多)。ContextSwitches是用户态和内核态之间切换的次数,高达3千1百多万次。左下角的Cycles是CPU执行该线程时所用的总时钟个数,7万多亿个。今天的x86处理器使用的超标量架构有4个发射端口,每次可以发出四条指令乱序执行,这意味着每个时钟周期可能执行多达四条指令。对于比较差的情况,平均每条指令所用的时钟周期(即所谓的CPI指标,CyclesPerInstruction)可能为3。按CPI为3来折算一下,CPU在这个线程上执行的指令数多达2万多亿条。2万多亿条指令是什么概念呢?曾经轰动信息产业的著名CIH病毒,总指令数只有几百条。即使按1千条来说,那么2万多亿条指令相当于把CIH病毒执行了20多亿次。(图3VTune显示的线程信息)图3是使用Intel的著名调优工具VTune分析管家程序时得到的线程信息。每行代表一个线程。需要说明的是,因为图2与图3是针对管家程序的不同运行实例,所以无法用线程ID把两个线程对应起来。但观察到的结论是一致的,从VTune视图来看,也是有四个线程很繁忙,而且有很频繁的线程上下文切换。VTune视图给我们的另一个信息是,有多个线程的执行过程都很有规律,尤其是第四个,每隔大约1秒(横轴为时间,单位为秒)有个尖峰,这说明该线程很可能是受定时器触发来工作的。_________________________________________________________________上调试器上面使用多个工具观察管家程序得到的结论都是它很忙碌。但不是很清楚到底是在忙什么?熟悉我的朋友一定想到了要上调试器。诚然,要想深刻认识软件,没有比调试器更有力的工具了。唤出WinDBG,附加到管家进程,一切顺利,先执行lm浏览模块信息(图4)。(图4模块列表(部分结果))图4中,第一行是EXE主模块,接下来的kernelbasis、kernel和kernelpromote三个模块的名字中都含有kernel字样,第一次看到这些名字让我一惊,以为与系统的kernel32和kernelbase模块有关,后来确认这是云管家自己的模块,我不禁好奇,这么高大上的名字,不知道出自哪位同行的妙想。顺便说一下,图4中以Yun开头的YunDb和YunLogic模块也是管家程序的重要模块,后文会提到。观察EXE模块的详细信息(图5),可以看到目前使用的是2016年3月的版本,这比我最初分析过的版本要新很多。(图5主模块的版本信息)(图6自动更新模块)在已经卸载的模块列表(图6)中,可以看到一个名为AutoUpdateUtil.dll的模块多次出现,它应该是用来做自动更新的。大致了解模块信息后,执行~*观察线程信息。哇,一共40多个线程。执行~*e.echo*;?@$tid;.ttime观察线程的执行时间信息,可以看到有几个线程的CPU累计时间都超过了秒级。这与前面使用ProcessExplorer看到的结果一致。做了以上观察后,执行g命令,希望让管家程序走走看。但是意外出现了,WinDBG很快收到了进程退出事件。第一次看到这一幕时,不禁愕然。凭借多年经验,我意识到这次的对手不一般,也是懂调试的,检测到调试器后,主动退出了。“你上调试器,我不跑了,死给你看。”________________________________________________________________解除了管家程序的反调试保护之后,可以进一步寻找它忙碌的原因了。经过一番勘察,我发现管家程序忙碌的第一个原因是非常频繁地分配和释放内存。长话短说,在WinDBG中设置如下断点来监视从堆上的内存分配。bpntdll!RtlAllocateHeap+5".echo**allocatingheap;r$t1=@$t1+1;?@$t1;kv;.if(poi(ebp+10)>10000){}.else{gc;}"先解释一下上面的断点命令,地址部分加5是为了越过函数开头的序言部分,以保证后面获取到参数值是准确的。双引号中包含了多条命令,先是显示提示信息,然后使用一个准变量来统计断点命中次数并打印出来,之后的kv是显示栈回溯,而后判断第三个参数所代表的分配大小是否超过1MB,如果超过则中断,不然则gc继续执行。设好以上断点,恢复目标执行,发现大量信息喷涌而出,如图9所示。(图9频繁的内存分配)等待5分钟左右,没有自动中断,说明没有发生参数超过1MB的调用,手工中断下来,可以看到$t1的累计值高达6万多次。0:043>?@$t1Evaluateexpression:61434=0000effa如果再设置如下断点监视释放堆块的行为,那么即使过了十几分钟之后,t1的值仍然不大。bpntdll!RtlFreeHeap+0x5".echo**Releasingheap;r$t1=@$t1-1;?@$t1;kv;gc"这说明很多内存块是分配了后,很快又释放掉了。有经验的程序员知道,从堆上分配内存是开销比较大的操作,好的程序应该尽可能减少从堆上分配内存的次数,分配好了的堆快如果将来还可能使用,那么最好重复使用,不要释放了又分配,分配了又释放。_____________________________________________________________枚举进程管家程序的更大问题是频繁调用很重的系统API。执行如下命令对系统的CrateToolhelp32SnapshotAPI设置断点。bpkernel32!CreateToolhelp32Snapshot".echocreatingsnapshot;?@$tid;r$t8=@$t8+1;?@$t8;kv;gc"禁止其他断点后,恢复目标执行,会发现这个断点命中的也很频繁。一分钟调用了100多次,大约每秒钟调用两次,如下图所示。(频繁调用CreateToolhelp32SnapshotAPI)熟悉Windows操作系统开发的朋友知道,CreateToolhelp32Snapshot的用途是对指定进程或者系统中的所有进程抓取快照。其函数原型为:bpkernel32!CreateToolhelp32Snapshot".echocreatingsnapshot;?@$tid;r$t8=@$t8+1;?@$t8;kv;gc"参考图10中的kv命令结果,可以看到dwFlags参数为2,代表TH32CS_SNAPPROCESS,意为包含系统中的所有进程。把上述断点中的gc去掉,不要自动恢复执行,断点命中后,一边观察任务管理器窗口,一边执行gu命令,执行完这个API后中断,可以发现每调用CreateToolhelp32Snapshot一次大约触发60多个缺页异常。CreateToolhelp32Snapshot返回的是一个句柄,通常拿到这个句柄后再反复调用Process32NextAPI来获取每个进程的信息。设置如下断点:HANDLEWINAPICreateToolhelp32Snapshot(_In_DWORDdwFlags,_In_DWORDth32ProcessID);恢复管家程序执行,可以看到以上断点果然反复命中。根据老雷的试验观察,每调用一次Process32NextWAPI,大约会触发8次缺页异常。管家程序每调用好一次CreateToolhelp32Snapshot后,会调用165次Process32NextW,那么这两项导致的缺页异常总数加起来便是1300多次,即:bpkernel32!Process32NextW".echoenumeratingeachprocess;r$t9=@$t9+1;?@$t9;gc"管家程序每秒钟会做两轮以上循环,于是便是2千多次了。值得说明的是,这个很重的循环操作发生在一个线程中,即前文所说图3中很有规律的第4个线程。有读者可能会问,如果每秒循环两次,那么图3中的尖峰应该是间隔半秒啊?其实不然,因为这个线程是连续循环两次。也就是每次唤醒后,连续做两次拍照和枚举,然后休息不到1秒再做两轮循环,如此往复。执行.ttime观察这个线程的执行时间,可以看到它的执行时间很长。0:017>.ttimeCreated:MonMay209:56:18.3772016(UTC+8:00)Kernel:0days0:02:45.579User:0days0:00:24.679执行~17n命令把这个线程临时挂起,恢复管家程序,再观察任务管理器,发现PFDelta(每秒钟新增的缺页异常)指标立刻降下来了,只有不到十次了。看来导致管家程序那么多的缺页异常的主要原因在于这个枚举系统进程的线程。它忙着给系统里的所有进程拍照,然后再一个个看过来。重要的是,这样的工作不是做一次,而是每秒来两轮,风雨无阻、孜孜不倦,时时刻刻关心着系统里运行着的其它进程,好辛劳的管家啊。软件的历史不长,但软件的孩提时代已经过去了,因为今天的软件已经丧失了曾经拥有的简单和纯真,变得复杂、贪婪和狡黠。一年多之前,我曾写过一篇《在调试器里看阿里的软件兵团》,批评了支付宝客户端软件中的性能问题,文章发表后,很高兴看到阿里的同行不断改进,今天已经不再有当时的问题了(图1中还可以看到淘宝的TBSecSvc进程,排名已经比较靠后)。不知百度的同行看过此文有何感想?作为一款客户端软件,能帮助用户管家是好想法,但是管家毕竟是仆人,有事时应该尽心给主人办事,没事时应该安安静静休息,不要肆意挥霍主人家的东西。

上一篇:魏大勋汪苏泷综艺节目 北京注册公司需要注意什么有哪些建议
下一篇:没有了
设为首页 | 保存到桌面 | 网站地图 | 用户帮助 | 用户注册 | 在线投稿 | 广告投放 | 留言反馈
Copyright © 2005-2012 ™ 165163.com.All Rights Reserved. 东阳在线版权所有
地址:浙江省东阳市画水镇华阳 电话:0579-86220017 013509201192 QQ:393614973 互联网ICP备案编号:浙ICP备10046462号
温馨提示:东阳在线所有帖子仅且代表作者本人意见,均不代表本站立场;如转载请注明出东阳在线(www.165163.com),商业用途请联系本站。

东阳E网 金华公安网监
s