http://mp.weixin.qq.com/s?__biz=MzA4Nzg5Nzc5OA==&mid=2651660539&idx=1&sn=f2edc0a0343c1c6bacc1c650176c3a68&scene=1&srcid=07028T3KHrglBvtsaEyjEPOG#wechat_redirect
请及时关注“高效运维(微信ID:greatops)”公众号,并置顶公众号,以免错过各种干货满满的原创文章。
作 者:史影(擅长运维开发、云存储、负载技术)、童宁(擅长监控、WEB前端技术)、张凯俊(擅长运维开发)
执笔人:韩晓光(专业运维,兼职开发,干过商务。信息系统项目管理师、ITIL Foundation认证、IBM CATE、RHCE)
作者团队著有《系统运维全面解析:技术、管理与实践》
由于操作系统自身问题,软硬件兼容问题,驱动问题、应用程序的bug问题以及各种复杂因素,都会导致运营的业务系统出现异常。对此,如果运维人员没有很好地分析处理能力,往往就会背黑锅。
那么作为运维人员,如何摆脱背黑锅的尴尬局面呢,也许Debug调试是一招破局必杀技能。
干运维,仅仅会Linux运维及其Debug调试是远远不够的,另外鉴于“高效运维”社区已经有介绍Linux调试专题文章,因此本文仅对Linux系统调试工具作简要介绍,而主要探讨Windows系统调试分析技术。
先说几个运维常见的尴尬场景:
1、用户反映系统慢,希望尽快解决。但你发现CPU、内存、磁盘、带宽等各项指标非常正常。于是问题僵持,用户很生气,你很委屈。
2、系统本来正常,但你发现自从部署某个应用后,系统就有些不正常了。但你苦于没有确凿证据去证明是这个应用软件的BUG。于是研发(产品)同事得意地笑了,你却很委屈地咬牙。
3、艾玛!系统出现故障,宕机了。然后你从系统日志里,并没找到问题的根源线索,或者看到了异常日志,也只是看看,然并卵。于是领导很生气,你依然很委屈。
如果你干过运维工作,那么上面的几个场景或许都会碰到过。也许我们会感慨运维就是“黑锅侠”,这就是干运维的命运,作为救火员,当你救不了火,那就背黑锅。
其实运维工作,难免遇见故障,是硬件总有罢工的那一天,是软件总有不合理的BUG、是人的地方就有江湖。作为运维工程师,要想成为运维大神,就得不断升级打怪,历经九九八十一难,你就得道了。
当你再蓦然回首,其实当年运维尴尬的背后,是我们当时无法定位妖怪的老巢,没法彻底一窝端掉。最核心原因是我们当时还不具备那种一捅到底的能力。
那么在这个快节奏运维年代,有没有速成的大法,直捣上述尴尬问题的底层原因呢?答案:有!
Debug调试分析!学得此本领,可以上天入地,干得了用户态,也搞得了内核态。
当然,有了这么好的大法秘籍,并非每个人都有机遇练就这身本领。所谓的速成,也看个人修为了。
接下来,我就简要介绍一些Debug调试大法。
我相信,秘籍不在长短,也不可能尽举。高手往往都是悟出来的。
作为运维工作,通常会分为传统运维、互联网运维。作为互联网运维工作者,我们通常用Linux系统。鉴于“高效运维”社区已经有介绍Linux调试专题文章,因此本文仅作一些Linux系统调试分析的概要介绍,不再赘述。
当Linux系统出了系统问题,程序问题,性能问题,怎么办?其实还是有很多工具方法可以用的。这里简单概括一下
点击可查看高清大图
运维的世界那么大,想成为一个运维大神,仅仅会Linux运维及其Debug调试是远远不够的。仅论服务器操作系统,还有AIX、HP-UX、Solaris、FreeBSD、Z/os、Windows,等等。
在传统运维企业及桌面运维中,其中Windows Server服务器还是占有相当的比重的。下面就探讨一下Windows系统调试分析。
2.1 Windows Debug及性能调试基础概念
2.1.1 名称概念
Process:进程,是操作系统结构的基础,是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。
Thread:线程,是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,它可与同属一个进程的其它线程共享进程所拥有的全部资源。
User Mode:用户态,应用程序运行时所处的模式,不能直接访问物理硬件及内存。
Kernel Mode:内核态,操作系统运行时所处的模式,可以访问系统的所有部分。
用户态与内核态的关系如图所示:
用户态模式包括:
用户的应用程序。
系统服务程序。
若干关键的系统进程,如Winlogon.exe、Csrss.exe、Lsass.exe。
内核态模式包括:
设备驱动。
系统组件。
硬件抽象层。
显示驱动。
Exception:异常,就是CPU在执行代码时,碰到的非预期的指令时所做出的反馈。它表明CPU需要中断当前正常执行的代码流程,去处理碰到的非正常情况。如:
除数为0。
页面错误,访问非法内存地址。
特殊的调试指令。
异常通常分为:
first chance — 程序不会崩溃;
second chance — 程序会崩溃。
在用户模式,大部分异常会被应用程序中的异常处理模块处理。如果程序没有正常处理这些异常,程序可能会异常退出。
在内核模式,系统异常处理模块会处理碰到的异常,部分异常会直接导致机器蓝屏出错。
简单来说,应用故障发生在用户态,系统故障发生在内核态。
Paging:换页,把物理内存中的数据移到磁盘上的PageFile中的操作。如果系统尝试访问PageFile中的数据,内存管理器会产生一个Page Fault,然后把相应数据重新从PageFile中读到物理内存中。
Paged pool:分页内存池,一部分内核使用的内存,可以被移到磁盘上的PageFile中。
NonPaged pool:非分页内存池,一部分内核使用的内存,需要一直保持在内存中,不能被移到磁盘的PageFile上,用于满足各种中断等需求。
Interrupt:中断,中断请求是由某个设备/进程发出的请求CPU产生中断当前执行流程的一个请求响应信号。
Blue Screens and Bug Check
Codes:蓝屏,系统碰到异常时,为保证数据完整性而把机器重启的保护机制,会同时显示蓝屏界面。
Crash Dump File:内存转储文件,系统蓝屏时,内存中记录系统状态的数据的文件转储。
2.1.2 系统常见性能问题与分析指标
常见性能问题:
CPU使用率高。
内存及内核资源使用。
磁盘性能问题分析。
系统失去响应及蓝屏重启。
常见性能分析指标:
内存
可用物理内存。
分页内存池。
非分布内存池。
缓存。
工作集空间。
CPU
CPU占用率(内核态CPU时间,用户态CPU时间)。
中断CPU时间与DPC(延时过程调用)CPU时间。
磁盘
磁盘忙碌\空闲时间比。
磁盘平均单次读写耗时。
磁盘IO排队队列。
Split IO/Sec。
2.1.3 内存地址空间分配架构
在x86系统上,虚拟地址空间是2^32=4GB。所以系统分配2GB给用户态,2GB给内核态使用。在内核态,我们可以使用/PAE的选项,来支持高达64GB的物理内存。
在x64的系统上,可以支持2TB的内存。
在Windows 2003及以前,内核虚拟地址空间是固定的。而在Windows 2008及以后,内核虚拟地址空间是动态分配的。
二者对比如图所示:
Windows进程使用内存的分配构成方式,如下图所示,其实是这样的。
英文解释如下:
Virtual Byte是整个进程占用的全部虚拟地址空间。包含保留和提交的内存。32位Windows用户模式下,进程默认最大可以使用2GB。在64位Windows下,进程的虚拟地址空间可以达到8TB。
Committed bytes 是虚拟地址空间正在被使用的那部分。这部分空间可以保证进程的地址可以映射到实际的物理内存(及磁盘page分页)上。
Private Bytes是只被本进程用占用的虚拟地址空间,不包括其他进程共享的内存。
Shared bytes 是与其他进程共享的一部分虚拟地址空间。
Working Set是一个进程可以用到(但不一定会使用)的物理内存。即不引起page
fault异常就能够访问的内存。Working Set包含了可能被其他程序共享的内存。
2.2 Debug调试常用概念
2.2.1 Windows系统有时候会出现死机及异常重启的情况,可能的现象例如:
机器非常慢,多个应用程序异常的慢,无法进行操作。
鼠标/键盘没有响应。
网络没有响应,PING/RDP/文件共享失败。
本地无法登录,桌面锁死,黑灰屏或是只有背景界面。
系统直接异常重启。
系统蓝屏。
出现上述情况的可能的原因:
硬件问题。
系统/应用程序死锁。
内核资源使用异常。
病毒/恶意软件。
2.2.2 调试系统死机/蓝屏的基本思路,如下:
检查系统日志,看是否有出错记录。
开启性能监控器,检查系统资源使用。
检查硬件。
卸载最近安装的软硬件。
用最后一次正常配置的模式恢复到之前的正常配置。
手动的收集死机时的DUMP文件。
收集系统蓝屏时的DUMP文件。
通过另一台机器进行Live debug。
2.2.3 DUMP概念
在系统蓝屏时,内核会尝试把当前内存中的数据保存下来,写成Memory.dmp文件,用于事后分析出错原因。
DUMP文件其实就是出错一瞬间,系统内存中内容的一份备份。它是一份静态的数据备份,并不是一个动态的一段时间内系统状态的记录。
2.2.4 DUMP文件类型
Complete Memory Dump 完全内存转储:系统蓝屏时,内存中的所有数据,包括用户态及内核态数据。该文件较大,一般就是当时内存使用大小。
ernel Memory Dump核心内存转储:系统蓝屏时,内存中内核态的数据。一般只在完全内存转储文件的1/3大小。
Small Memory Dump (“Minidump”):包括最基本的调试信息,如loaded drivers、kernel-mode stack、出错代码等。较小,64KB–256KB。
2.2.5 DUMP文件调试工具
调试的配置及分析工具有很多,例如:
Windbg:即可分析用户态dump,也可以分析内核态dump
gflags :Windbg中的gflag.exe,能够很好地分析捕获heap破坏异常问题。
Adplus: 能够交互式分析停止响应(挂起)或失败(崩溃)的进程或应用程序的问题。
debug diagnostic:可以自动分析用户态dump文件,但不能分析内核dump(如系统蓝屏dump)。可以很好地分析定位内存泄露问题。
visual studio: 只能分析用户态dump
perfmon:Windows系统默认自带的性能分析工具。其实是很好很强大的。用得好不好,就看你对Windows了解有多深了。
PAL:通过PAL分析perfmon的性能日志文件,可以自动产生一个网页版的性能分析报告,大大方便了我们分析系统性能工作,是一款非常好用的性能分析辅助工具。
2.2.6 Windbg简介
Windbg是常用而且强大的Windows调试分析工具,界面如图17-10所示。
Windows debugger安装程序下载地址:
X86:
http://msdl.microsoft.com/download/symbols/debuggers/dbg_x86_6.11.1.404.msi
X64:
http://msdl.microsoft.com/download/symbols/debuggers/dbg_amd64_6.11.1.404.msi
一般情况,我们使用Windbg工具进行DUMP调试。
Windbg 也可以用于代码调试及实时调试。除了直接安装Windbg,我们也可以把其它机器上安装好的Windbg文件夹直接拷贝到另一台机器上即可使用。
Windbg Symbol 文件
在Windows 系统中,Symbol文件以.pdb 为扩展名。
Symbol Files是一个数据信息文件,它包含了应用程序二进制文件(比如EXE、DLL等)调试信息,专门用于调试时解释可执行文件中的变量信息。
WindowsPublic Symbol 地址:
http://msdl.microsoft.com/download/symbols
Private Symbols 包含更多的信息,如本地变量名、源程序行、变量类型等信息。
有很多信息在public symbol中是看不到的,但是这些信息只限于操作系统内核,即使有private symbol,也需要配合source code一起分析。
Windbg中设置Symbol Path
设置Symbol的目的是告诉debugger哪里去对应或下载相应的Symbol files。
设置Symbol时,可以包含多个路径,包换Microsoft Symbol服务器、本地Symbol路径、内部Symbol文件共享、程序开发时创建的Symbol等。这些路径以“;”分隔。
Symbol path 示例如下:
SRVc:\symbolshttp://msdl.microsoft.com/download/symbols
WinDbg中四种方法设置symbol path
Set the _NT_SYMBOL_PATH environment variable
Use the -y command line option
Use the .sympath (Set Symbol Path) debugger meta-command
Use the “Symbol File Path” command in the File menu
Windbg基本使用方法
当打开一个dump文件,!analyze –v是唯一默认出现在Windbg中的命令。这个命令可以查看关于此DUMP文件的最基本的信息,如下示例:
点击可查看高清大图
在检查完!analyze –v的输出后,我们需要切换到出错当时的frame(单击出现的trap 命令),然后用k命令检查真正出错时的stack:
点击可查看高清大图
其它可能出现的trap的形式有:
.tss/.exr/.cxr/.trap
在!analyze –v的输出中,Windbg会自动指出最可能出错的驱动,例如:
点击可查看高清大图
这个结果其实是Windbg自动把stack上出现的驱动,按出现顺序的由后到前,与…\Debugging Tools for Windows (x64)\triage\triage.ini 中列出的驱动进行比较后过滤,当过滤到第一个没有记录在triage.ini中的驱动时,把它列为可能引起出错的程序。
所以Windbg自动分析出来的这个结果,并不是100%完全可信,仅可以作为参考。
2.3 Windbg debug调试分析实例
2.3.1 案例:关于应用dump文件的分析
问题描述:
这个是一个基于.NET开发的应用程序,之前一直运行良好,但现在只要一按附栏中的“校验”,就会产生错误,如图所示:
问题分析:
首先,收集应用程序dump,抓取dump文件,方法如下:
1)运行程序Windbg
2)打开命令行(cmd.exe), 将当前目录切换至c:\debuggers(Windbg的安装目录),
在问题重现之前输入以下语法格式命令用以开始监视目标进程:
cscript adplus.vbs -quiet –crash -fullonfirst -pn.exe -o c:\dumps
例如这里输入命令:
C:\Debuggers>cscript adplus.vbs -quiet -crash -fullonfirst -pn Arms.Server.Remoting.exe -o d:\dumps
3)回到程序并重现问题。
注意:如果C:\盘空间不足的话,可以将dump生成目录(c:\dumps)更改到其他位置(例如这里设置为d:\dumps)。请不要手动关闭debugger窗口(cdb.exe),当应用程序重现问题之后这个窗口会自动关闭。
4)当问题重现时,也就是您看到错误对话框以后,请不要关闭那个错误框,之后打开命令行,输入以下命令收取一个新的dump文件。
cscript adplus.vbs -hang -pn Arms.Server.Remoting.exe -o d:\dumps
通过上述步骤,也即在hang模式下抓取了dump文件,例如这里抓取的dump文件名称为:
[PID-3436ARMS.SERVER.REMOTING.EXEfull_0268_2012-11-28_10-06-00-687_0d6c.dmp]
通过Windbg打开该dump文件,主要分析要点如下:
点击可查看高清大图
分析结论:
从Windbg分析来看,其调用的栈应是一个Windows Service程序。
从上述提供的报错截图来看,抛错的程序应就是一个Winform的程序,基本上与该dump分析出来的堆栈信息一致。因此该程序这段代码出错的可能性很大。
从而基本排除系统层面的问题,并且大致定位到应用程序的故障范围。剩下问题就是扔给应用开发人员调试程序。
至此,作为运维的你是不是感觉清爽了很多,起码摆脱了黑锅。
2.3.2 案例: 关于系统dump的调试分析
问题描述:
windows服务器异常宕机,已产生dump
问题分析:
使用Windbg对系统dump进行分析。
主要分析内容如下:
分析总结:
服务器发生蓝屏的直接原因是一个驱动程序尝试去在一个过高的IRQL(Interrupt ReQuest Level)上访问一个被换页的内存(也有可能是不合法的内存地址)。
通常情况是由驱动访问不合法的地址造成的。经过检查DUMP,我们发现SYMTDI很有可能是导致蓝屏的原因,同时由于系统并未升级到最新版本,建议做版本升级。
GetAddress是windows系统函数,出错的具体原因是tcpip对一个irp(I/O Request Package)的对象做检查的时候出现异常。
这个irp是从rpcxdr下发,经过symtdi,最后到了tcpip,因此怀疑可能是symtdi或者rpcxdr的问题,因此建议升级symtdi和tcpip.sys到最新版本(从时间戳来看,驱动是有些老旧),并继续观察服务器运行状况。
限于篇幅和作者水平,就先到此吧。
想了解IT运维更多内容,请参阅:
作者书籍:
《系统运维全面解析:技术、管理与实践》