• 利用Performance Counter Alert辅助调试


    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等调试工具,可以帮助开发者在第一时间获取程序状态,进行高效的调试。

  • 相关阅读:
    第六节
    第十节
    第七节
    【项目】项目163
    【项目】项目165
    【项目】项目164
    【项目】项目168
    【项目】项目166
    【项目】项目167
    7.Redis之Sentinel安装与部署
  • 原文地址:https://www.cnblogs.com/liangshi/p/1747524.html
Copyright © 2020-2023  润新知