Chinaunix首页 | 论坛 | 博客
  • 博客访问: 367977
  • 博文数量: 715
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 5005
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 14:46
文章分类

全部博文(715)

文章存档

2011年(1)

2008年(714)

我的朋友

分类:

2008-10-13 16:30:41

除虫记之十一:流程错了(1人/3小时)

我们即时通的音视频功能进入测试了,我总算快熬出头了,因为要求我对该项目放手太松(个中原因....唉....),项目出了各种问题,等发觉需要我全力扑上来时,项目差不多进入了游离状态,我极力的推动、积极沟通,总算让项目组正常工作,期间我承担了太多的压力,发版日期一推再推,现在项目送测,实在是让我有中云开日出的感觉。但........

上午刚到公司,项目经理告诉我程序有崩溃,对方窗口关闭时,己方崩了。我ft,怎么每次都关键时候掉链子呢,追问,得知是一个能重现的崩溃,这下送了口气,既然能重现,那就很容易解决了。再仔细问了问,说大概定位了,是视频显示窗口的句柄为空什么的,这下就更放心了,这小case,告诉他跟踪,解决了后重新送测。

一上午追问了几次,说正在解决中。

上午,大老总带了两个女士来看我们的音视频功能,不知什么来头,并亲自做了测试,感觉不错。她们没有关窗口。

吃过中午饭,负责我们研发中心的老总来询问测试情况,和项目经理沟通。项目经理把这个bug做了汇报,并说明了解决办法。我问bug的原因是什么,被告知不清楚,没有找到真正原因,把引起出错的那一段代码换了一种方式了事。我ft,当即指出这样不行,即使可以通过更换实现方式解决也要搞清出错的原因,否则还会有隐患。老总也做了同样的指示。

要求下午查清,等了一会,发现没有什么进展,唉,还是亲自来吧。

程序是在Release版下运行的,为了跟踪,我加上了调试信息,没有设置断点,运行,聊天,音视频,通了,声音和图像质量确实不错。让对方关闭窗口,崩了,查看调用堆栈,发现是崩在界面处理上。回朔查看没有发现什么端倪。

设置断点,运行,聊天,音视频,通了,声音和图像质量真的不错。对方关闭窗口,进入断点,下面的工作就是停止音视频的各个Graph,然后把界面回退到普通的聊天界面。
单步运行,停止Graph没有出错,调整界面,崩了,再来一次,进入调整界面的代码,因为界面的派生关系比较复杂,一个一个的虚函数和基类的调整界面代码真是麻烦,中间发现了一个错误,一些界面调整函数重复调用了两次,是不是因为重复调用引起的??

修改代码,把重复调用去掉,重新运行,还是崩溃,这次崩的位置是在我们的CoolSkin界面库里面。再次运行,还是崩在界面库里面。

把界面库的代码拿过来,编译成带调试信息的Release版,运行,发现是崩在CStatic派生类CCoolStatic的析构里面。
这个界面库可以说是酒精考验了,不太可能是因为这个原因的。但明明是这个派生类析构结束后就崩了的呀。晕了。

有电话要我去开会,告诉他们先按他们修改过的代码继续测试,这个崩溃我开完会再查。

晚上加班,订丽华快餐,现在看到这盒饭都有点反胃,想吃老婆做的馒头咸菜鸡蛋白汤,更可气的是他妈的丽华快餐如果不明确要求带发票来,他们就不带!

从vss上更新最新代码,发现自己好长时间没有更新相关的工程代码了。

编译,期间又去开了个会,开会期间又被告知有人来面试,公司HR从网上搜了一个人才,竟然约到晚上7点半来面试!

面试回来,饭都有点凉了。

编译完,运行测试,在我的机器上也是这个错误,仍然崩溃在CCoolStatic析构之后。

把界面上的这个对象从CCoolStatic换成MFC的CStatic,编译运行,仍然崩溃,崩在MFC42的11c7偏移地址处。查看这个地址,发现是在PumpMessage函数中出了错误!tnnd,啥个子消息在捣鬼???

好办,从CStatic新派生一个类,重载WindowProc函数,断点运行,发现崩溃之前竟然没有任何消息!

把exe编译成Debug版本,运行,也崩溃,这次明确指示了崩溃的地方,在DestroyWindow函数里面,afxMapHWND()得到了一个空的CHandleMap指针。

哈,经验立刻告诉我,肯定是对这个窗口句柄做了什么不配对的Attach/Detach操作或者复制继承等,没有正确释放对这个窗口的控制造成的。

这个CStatic窗口是传给DirectShow用来显示视频用的,立刻叫来项目经理询问,是不是对这个窗口做了不应该的Attach/Detach操作?
被告知没有,仅仅是把窗口传给了Graph而已,审核代码,确实没有Attach/Detach操作,到底是哪儿出了问题?

因为崩溃很明显是因为这个句柄的问题,坚定信心,一个一个调用函数的追踪,看看到底对这个句柄都干了些啥!

调用真够复杂的,一个一个函数的调用,句柄被做为参数传进来、传出去、再传进来、再传出去、再....,这么折腾,幸亏是句柄,如果是人柄估计歇菜了。终于在最后看到了一处可疑的地方,句柄传到了IVideoWindow派生类里面,在交给Graph后,做了一个put_Owner()调用,立刻想到,Graph销毁前是不是应该把窗口句柄释放?
查看MSDN,果然呀,里面写的清清楚楚:After using this method to set the owner of a video window, you must reset the owner to NULL (by calling put_Owner(NULL)) before releasing the filter graph. Otherwise, messages will continue to be sent to this window and errors will likely occur when the application is terminated.
哈哈,立刻断定,就是这个原因!

告诉他们,Graph销毁前没有做put_Owner(0)操作!

可...一个开发人员告诉我,这个操作在IVideoWindow派生类的析构里面做了的,审核代码,果然有!

会不会没有执行这段代码呢?

跟踪运行!果然没有执行析构操作!

现在可以定位了,程序流程中出了问题,Graph停止后没有销毁实例。

让项目经理去解决这个问题。
我同时写这篇随笔。
告诉他,我写完随笔的时候,这个bug应该解决才行。

结果.....随笔写完了,bug还没解决!

教训:1、如果早一点编译debug版,能节省一个小时。
            2、afxMapHWND()出了问题,就顺着这个窗口句柄追吧,肯定没有错!

 


--------------------next---------------------

阅读(165) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~