All About Smart Testing

利用Performance Counter Alert辅助调试

上一篇 / 下一篇  2010-05-30 18:18:07 / 个人分类:调试

51Testing论坛上,有一位网友提出一个问题:应用程序运行1小时左右,会占用CPU 近100%,持续1~2分钟后恢复正常,有没有诊断方法?

20100512_ff527eb389005249b527OgDBBZxAROnd

.NET 2.0应用程序调试》和《Windows用户态程序高效排错》都指出,开发者可以用Performance Monitor监视特定的Performance Counter,当Counter的值超过预定义阈值时,Performance Monitor会调用开发者指定的任务。这个任务通常是使用调试器Windbg生成程序的内存转储文件(memory dump file),然后分析该文件,调查当时程序的状态。对于上面这个案例,应该用Performance Monitor监控该程序的“Processor Time %”,一旦它超过90,就利用调试器生成其内存转储文件。

自Windows Vista开始,Windows改变了Performance Monitor的界面,使得上述功能的“可发现性”大大降低。再加上Windows帮助和MSDN也语焉不详,使得开发者在使用上有一些困难。本文将介绍在Windows 7上,如何利用Performance Counter Alert进行调试。

1. 创建Performance Counter Alert

点击 Start > Administrative Tools > Computer Manager,展开节点System Tools > Performance > Data Collector Sets > User Defined,右键点击User Defined,创建Data Collector Set。

capture_30052010_154259

在弹出窗口中,将Name修改为cpu_usage_alert,选择 Create manually (Advanced),点击Next。

capture_30052010_154801

选择 Performance Counter Alert,点击Next。

capture_30052010_154951

点击 Add… ,以加入Performance counter。

capture_30052010_155420

在弹出窗口中,选择 Process下的 % Processor Time,然后选择目标进程(在下图中,我选择的是taskmgr,即任务管理器),然后点击 Add >>,最后点击OK。

capture_30052010_155256

将Limit修改为90,点击Finish,完成 Performance Alert 的创建。

capture_30052010_155328

在 Computer Management中,点击cpu_usage_alert,在右侧窗格中,右击DataCollector01,点击Properties。

capture_30052010_160047

在弹出窗口中,点击Alert Task,将 Run this task when an alert is triggered 修改为cpu_usage_alert_task,最后点击OK。

capture_30052010_160118

选中cpu_usage_alert,然后点击工具栏上的 Start the Data Collect Set,开始监控性能数据。

capture_30052010_173500

这样,我就创建一个Performance Counter Alert,它监控任务管理(taskmgr.exe)的CPU占用率,一旦其超过90%,就会触发任务cpu_usage_alert_task。在Windows XP和Windows Server 2003中,任务可以是任意程序和脚本。但是,在Windows 7中,任务必须是一个Windows Task。

2. 创建Task

在 Computer Manager中,展开节点 Task Scheduler > Task Scheduler Library,右键点击Task Scheduler Library,点击 Create Task… 。

capture_30052010_161241

在弹出窗口中,将General中的Name修改为cpu_usage_alert_task(即cpu_usage_alert所触发的Task的名字)。

capture_30052010_161919

在Actions中,点击New… 。

capture_30052010_161336

在弹出窗口中,将 Program/script. 修改为 c:\debuggers\cpu_usage_alert.bat。最后连续点击OK,完成Task的创建。

capture_30052010_163041

当cpu_usage_alert_task被触发时,Action所指定的脚本cpu_usage_alert.bat将被执行,它调用Windbg生成内存转储文件。

3. cpu_usage_alert.bat

cpu_usage_alert.bat的内容很简单,只有一行脚本:

"c:\debuggers\ntsd.exe" –pn taskmgr.exe -c ".dump /ma /u C:\debuggers\taskmgr.dmp;qd"

此脚本要求将Windbg安装在 c:\debuggers 目录下。它调用调试器 ntsd.exe,对进程taskmgr.exe生成内存转储文件。ntsd命令的详细解释如下。

  • -pn taskmgr.exe:对进程taskmgr.exe进行调试。
  • -c ".dump /ma /u C:\debuggers\taskmgr.dmp;qd":执行调试命令.dump和qd。
  • .dump /ma: 生成小型内存转储文件。
  • /u:将时间戳和进程ID加入到内存转储文件名。这可以保证连续生成的内存转储文件不会同名。
  • C:\debuggers\taskmgr.dmp:将内存转储文件生成到 c:\debuggers 目录下,文件名以taskmgr开始。
  • qd:将调试器与taskmgr.exe分离,并关闭调试器。

于是,当cpu_usage_alert发现taskmgr.exe的CPU占用率超过90%,它会触发cpu_usage_alert_task,后者会调用cpu_usage_alert.bat,生成taskmgr.exe的内存转储文件。这样的脚本适合产品环境,它没有中断被调试对象的执行,只是保存了内存转储文件。当系统管理员将内存转储文件移交给开发团队,开发团队可以对其进行“事后分析”。

值得一提的是,如果cpu_usage_alert的采样频率是15秒,那么cpu_usage_alert.bat将会每15秒生成一个内存转储文件。如果taskmgr.exe的CPU占用率持续超过90%,cpu_usage_alert.bat将生成大量的内存转储文件,有可能耗尽磁盘空间。因此建议将转储文件生成在非系统盘,且该磁盘拥有充足的容量。

capture_30052010_165458

如果在测试环境中调试,可以考虑将cpu_usage_alert.bat实现为:

"c:\debuggers\ntsd.exe" -server tcp:port=8888 -pn taskmgr.exe -c ".dump /ma /u C:\Dump\%name%.dmp"

该脚本仍旧生成内存转储文件,因为内存转储文件保留了“问题现场”,是非常重要的调试信息,要第一时间保存。它与产品环境脚本的不同之处在于:

  • 不调用qd:生成内存转储文件之后,不与taskmgr.exe分离,不关闭调试器。
  • 利用参数 –server tcp:port=8888开启了一个调试服务器。由于ntsd一直附加(attach)在taskmgr.exe之上,开发者可以用Windbg(远程)连接该调试服务器。详细操作请参考博文Remote debugging with -server and -remote

那么,开发者如何知道可以开始调试了呢?可以在cpu_usage_alert_task的Action中,再加入一条发送邮件的操作。在下图中,我利用一个IronPython脚本mail.py发送一封邮件题为 “cpu usage alert” 的邮件到我的邮箱。在Windows上有许多命令行的邮件客户端,也可以完成类似操作。

capture_30052010_173056

4. 小结

Performance Counter Alert是一个强大的性能诊断工具,能够及时捕获性能异常事件。配合Windbg等调试工具,可以帮助开发者在第一时间获取程序状态,进行高效的调试。


TAG:

引用 删除 翦砃   /   2010-09-06 16:09:45
5
引用 删除 墨卓   /   2010-06-01 12:17:27
顶一个,虽然不用这个
 

评分:0

我来说两句

Open Toolbar