解BUG的一些心得

目前,软件BUG一直是程序员的梦魇,但其实只要掌握一定的技巧和基本知识, 是可以轻松解决掉这些BUG的。

以下一些BUG是在程序开发中相对比较棘手的问题:

1、程序跑一段时间以后会越跑越慢。

2、程序无缘无故Crash。

3、程序内存越变越大,直至程序Crash。

4、程序跑着突然死掉了。

 

一、定位线程。

以上解决问题的关键是先定位到程序变慢的代码,对于第1、4点,可以先确定是哪个线程出了问题, 因此,小弟不才区区在下我编写了一个监控线程信息的程序,这在自己的开发还是发挥一些作用的。 界面如下,

tm

 

Load Process:可以获得当前系统的所有进程。

Detect:是对被选择的进程进行监控。

Detect下面的列表监控参数如下:

ID:线程ID

Name:线程入口函数名:

Address:线程入口地址

Kernel Time:线程占用的内核时间

User Time:线程占用的用户时间

Percent:线程CPU利用率。

Affinity:线程的亲缘性,即线程指定运行CPU参数

 

由于,用Windows API很难获取线程的Address,所以需要编写驱动程序去获取内核线程信息ETHREAD和KTHREAD,

以上,ID、Address、Kernel Time、User Time、Affinity可以由该驱动去获得,而Name需要配合EXE、DLL对应的PBD

文件来获取,最后Percent可以自己利用Kernel Time和User Time来计算大概的CPU利用率。

 

利用以上工具,可以方便的知道系统到底有几个线程,每个线程名称又是什么,他们的一些信息又是怎样的?

 

1、在开发过程中有时会发现程序占用太大CPU资源,这时候,你可能苦于不知道是哪个线程,那段代码出了问题。

     现在,你可以使用该工具,它很方便的找到CPU资源高占用的线程,然后可以结合代码时间计算程序,找到

     CPU资源高占用的代码。

2、有时程序莫名奇妙跑着会变慢,这时你可以利用该工具看下,到底是哪个线程占用比较多的CPU时间,它又是在哪个CPU下运行的。

     曾经我就碰到过这样的问题,最后,我用该工具发现,有两个线程共享一个内存,而它们又分配在不同的CPU下运行,这会导致CPU

     的Cache无法很有效的利用,这会导致程序在某些操作系统下,会越跑越慢。最后,我用SetThreadAffinityMask把两个线程设定

     在同一个CPU,问题居然神奇的解决了。

 

二、Fix变慢问题。

对于变慢的问题,找到了变慢线程后,可以利用计算代码时间的方法找到变慢的代码,从而解决问题。

实战,

问题:DirectDraw画图操作经过长时间运行以后,会变慢。

解决过程:对绘图操作各个代码段加上计算时间的代码,发现DirectDraw在调用GetDC获取DirectDraw DC以后,

              直至ReleaseDC这个过程变慢很明显。然后再进行细化,发现是CDC::FromHandle出了问题。

原因是:CDC::FromHandle会根据传进去的HDC去查找MFC已知的HDC+CDC映射表,如果找到则返回对应的CDC,

           否则,创建一项映射关系。问题的关键在于,该映射表会不断膨胀,导致查找速度越来越慢,所以绘图操作越来越慢。

           那为什么该映射表会不断膨胀呢?因为,DirectDraw在不断释放和初始化,所以它的GetDC会返回不同的HDC句柄,

           但,DirectDraw DC释放后又没有释放HDC+CDC映射表对应表项。

经验教训:如果代码中使用SDK的CreateDC或GetDC,最好不要使用CDC::FromHandle,这会导致MFC的HDC+CDC映射表

              不断膨胀。

 

 三、Fix程序死掉的问题。

对于死掉的问题,可能是死锁导致,首要就是找到死掉的线程。

要找到死掉的线程,可以遍历所有线程,并把所有线程的上下文Trace出来,就可以知道到底在哪些线程出现了死锁。

要把所有线程上下文Trace出来,可以用GetThreadContext函数。

GetThreadContext只能在所在进程生效,这时你可以采用CreateRemoteThread的方法把你的GetThreadContext代码

嵌入到目标进程,再使用共享内存把采集到的Thread Context传到源进程。但要记住使用GetThreadContext函数前要先

SuspendThread,完了再ResumeThread。

知道了死锁的线程和位置,就可以分析代码,找到死锁的原因,并解决问题。

 

未完待续。。。

需要和我探讨的朋友,请加我QQ363169978

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值