1。 删除仍然需要被使用的指针。
对于QT,如果有两个slot被连接到同一个signal上,在第一个slot中删除Signal Sender, 由于SignalSender的指针仍然在栈中,并且在处理下一个slot时需要被使用,造成程序会随机crash,而且crash时的backtrace可能已经被破坏。
最好不要再slot中删除SignalSender。
Signal-Slot模型虽然很好用,但也欺骗了我们,我们可能会误认为slot是从processEvents()中直接调用的,其实不然。考察signal-slot的实现我们就知道在调用栈中还存在着大量的关于调用对象的指针,在slot里对这些进行操作都是非常危险的。
在普通应用里其实也有类似的问题,只是不如Signal-Slot那样具有欺骗性罢了。
2。空指针
无话可说,只能尽力避免,而且产生的原因也多种多样,比如没有初始化,内存分配失败,接口定义 模糊等。但是这样的问题比较容易查找,基于Debug的coredump可以给出真实可靠的信息。
3。悬挂指针(野指针) 一般的,C++中允许指针具有多个副本,而副本持有者都有能力去做任何操作。这样由于不小心造成的野指针比比皆是。表现出来的行为也很诡异,出现的问题的地方可能离rootcause很远了,而且有时候不会crash但是行为无法预测。
在coredump中一般表现为
“access denied”
在多线程情况下,公用数据有可能变成野指针。
5. 多次delete或free同一个指针
crash的时候可能会引发SIGABRT(6),这是因为free()函数中会触发abort().
6。重入
这个问题多发生在人机交互上,由于一个动作的处理需要一定的时间,用户可能在一个界面命令完成之前(界面还没有切换)就触发了另一个命令,这可能是一个预料之外的用例。有时候还仍然工作正常,但由于内部多执行了一些操作,有可能数据已经损坏。
7。多线程操作UI
UI是一个复杂的资源,很多UI framework都默认为单线程操作UI,这样UI库中的很多数据就可以设计为global和static的,但是在多线程情况下,尤其是播放视频等需要大量线程控制的情况下更容易出现这样的问题。