Windows下问题定位

 1、内存相关知识点;

1)windows下32位进程,用户态为2G内存,内核态也为2G内存;却别于linux操作系统;      

备注:可以通过命令行与管理员权限,启动3G的用户态空间,但是部分内核态的驱动等可能存在问题,需要实际测试。                

两个操作系统的设计为什么会存在1G的差别????

2)物理内存与虚拟内存;保留内存与提交内存的却别与实际影响;        

物理内存: 实际机箱里面插的物理内存条;在满足操作系统运行的条件下,只影响操作系统下面程序运行的速度,不影响程序的功能。          

虚拟内存:从硬盘上面划分的用于物理内存的扩展,对普通程序员影响不大,也可以理解为虚拟内存页;          

保留内存与提交内存:一个32位进程的2G的逻辑内存空间的存在形态。2G内存是一个32位进程可以使用的最大空间,OS层面为了提高内存分配的效率,保留内存用户可以不再关心,如果在window XP下面需要通过该参数确认是否发生了内存碎片,当前vista操作系统后,该问题已经不存在。

3)虚拟内存上涨到2G,一般32位应用程序肯定会出现内存不足而产生崩溃; 备注:Calc.exe的内存当前占用为99.440M,不要给任务管理器中的10M迷惑(提交内存),实际经占用了

扫描二维码关注公众号,回复: 16334853 查看本文章
 2.内存函数调用:

 3.异常处理流程:

1)windows下进程的运行操作系统提供了完善的异常保护机制 !teb查看某个线程是否添加了异常保护,为了提升异常相应的速度,异常控制块FS放置在Teb的句柄首地址 ExceptionList为异常处理列表,当有异常发生时,windows的处理流程如下 1、线程出现异常时,查询当前进程的调试端口是否打开,如果时直接进行调试状态

2)获取ExceptionList的第一个FS[0]的控制器进行处理异常,如果处理成功则继续运行(如try catch)       也有可能处理完成后,进程退出了,如自动抓取dump功能,直接上在teb上登记了异常处理控制块,写完dump文件后退出了

3)也可以弹出错误框由用户决定是否继续运行,如runtimes error类错误,可以继续运行,如果否则进入下一个异常处理控制块

4)如果所有的控制块都没有处理异常,则进入windows UnhandleExceptionFilter函数控制块进行处理

4.Windbg常用命令:

Windbg:等同于linux下面的GDB,可以直接在客户机器上面远程调试
Version,操作系统版本,异常等崩溃抓取的时间
!peb   进程等相关信息,如属于哪个程序崩溃了,一些环境变量配置是否正确
 !runaway  程序运行的时间,如果太短是否属于已启动就崩溃(配置文件等损坏)
!teb 
Kv, !heap,lmvm等命令,使用windbg的se指令,wt,bm,windbg自带的事件指令
dps  ln(查询最接近的函数符号)

现场崩溃位置查询,找到崩溃的现场整理出崩溃的代码行->进行崩溃代码行分析 
.thread     --线程控制块
dd/!teb  线程控制块地址
.dps   进行栈信息打印    ------打印整个线程的栈信息
.dps  esp  esp + 200进行打印   ---  打印部分栈信息

//将64位操作系统的dump切换为32位操作系统环境
.load wow64exts


!sw
//windows异常问题定位
!findstack kernel32!UnhandleExceptionFilter
!findstack ntdll!KiUserExceptionDispatcher
!findstack ntdll!RtlEnterCriticalSection
!cs


//内存泄露
gflags.exe  /i Excute.exe
set _NT_SYMBOL_PATH=C:\Users\Symbals
umdh.exe -p:12345 > d:\MemorySnap1.txt
umdh.exe -p:12345 > d:\MemorySnap2.txt
umdh.exe -d d:\MemorySnap1.txt d:\MemorySnap2.txt > d:\MemoryCmp.txt

操作:D:\2.学习文件\window下问题定位\测试dump信息\王根岭  
措施: 关闭 New抛异常,当内存不足时,直接返回空指针

5.定位的一般原理与步骤:

1)确认问题属于哪一类,内存泄露、踩内存、死锁、句柄泄露等…………

2)句柄泄露与内存泄露
      采用快照的形式,在进程运行的不同时间段抓取不同的snap,然后比较不同时间段的snap的差异类确认内存泄露的代码位置。 需要开启ust (Create user mode stack trace database)

3)踩内存多线程等相关问题,开启页堆进行问题复现。采用的原理:每个内存页都可以单独设置访问属性,申请的内存高地址4K对齐,同时添加一个4K的隔离页面。这样用户如果操作时,只要写越界,就会触发内存访问错误。这个也就是开启页堆后内存上升很快的原因,同linux下面的vrigrande工具

6.辅助工具:

1)使用procexp查看进程是否异常,内存是否异常,句柄是否泄漏,进程是否死锁,线程是否有泄漏等
2)windbg 查看崩溃时候的dump信息,找到崩溃问题
3)内存泄漏使用umdh进行比较,查询到泄漏的代码行------问题能复现
4)句柄泄漏可以直接使用windbg的!htrace进行跟踪,也可以采用umdh进行定位
5)当出现崩溃或者多线程等难浮现问题。直接搭建环境,进行ApplicationVerifier验证
   (正式的交付件应该都需要该工具测试,但是只需要关注多线程,内存踩踏类问题)
6)使用dbgdiag等工具进行崩溃、内存泄露等相关分析,可以只开启ust开关
7)内存泄露不能复现,只能借助dbgdiag或者windbg Heap命令进行分析,找到哪块大小的内存出现了泄露

备注:
当前讲解Vista,Win7\8类内部实现类文档比较少,原先的一些工具等有的已经不是很好使用,因此建议由XP的机器,可以先在XP下面进行稳定性测试,出现问题也比较好定位,如!address可以直接查看剩余堆块大小

7.参考资料:

猜你喜欢

转载自blog.csdn.net/huapeng_guo/article/details/132360033