买了某厂商的手机, 用着其实还蛮不错, 但会出现低概率开机卡死的问题, 或许是职业习惯的原因, 打算就此时小小地写一下。
低概率问题, 很不好重现和定位, 但又不能忽视。如果死机出现的概率为1/100, 那么100w台手机, 也会有10000台手机有问题, 用户肯定在网上炸开了锅。下面来简要说一下, 比如, 假设手机在启动AAA某块时候, 低概率卡死, 简要代码如下:
#include <iostream>
using namespace std;
void startAAA()
{
// 启动AAA模块 ...
}
int main()
{
printf("flag1");
startAAA();
printf("flag2");
// ...
while(1);
return 0;
}
这样, 我们只能在日志中看到flag1的打印, 看不到flag2. 但这是个低概率问题, 测试人员偶然发现了, 但开发人员每次去重启手机, 又没有发现。 那怎么办呢? 肯定不能放任bug不管啊, 也不能让所有开发人员去手动重启盒子, 天天在那里尝试啊。 所以, 我们要找到自动重现问题的方法, 例如(伪代码示意):
// 伪代码, 不能直接运行
#include <iostream>
using namespace std;
void startAAA()
{
// 启动AAA模块 ...
}
void myThreadFun() // 线程函数
{
Sleep(1000 * 300); // 停留5分钟
printf("creat core");
createCore(); // 产生core文件, 一般伴随着重启手机, 所以就不显式调用rebootCellphone了
}
int main()
{
createTestThread(myThreadFun); // 创建线程
printf("flag1");
startAAA(); // 低概率卡死在此处
printf("flag2");
rebootCellphone(); // 重启手机
// ...
while(1);
return 0;
}
我们来简要分析一下:
(1)当AAA模块启动正常的时候(一般肯定不需要5分钟), 线程函数myThreadFun中的createCore根本来不及执行, 而主线程中的rebootCellphone函数会使手机重启, 此时不会有core产生, 于是自动进行下一轮开机测试。
(2)当卡死在AAA模块的时候, 显然就不会直接走到flag2和后面的rebootCellphoe函数, 此时,经过5分钟后, 线程函数myThreadFun中的createCore会产生core, 并自动重启进入下一轮测试。
记得保存日志, 剩下的工作就是分析日志和core了, 当然, 主要是core.
最后说一下, 要对自己的产品负责, 要对用户负责, 忽悠用户, 最终只能被用户抛弃!