嵌入式linux 多线程卡死

在一台跑2.6内核的嵌入式linux设备上(可视对讲门口机),大概有十几个进程,其中自己的应用程序占用1个hicore进程,里面大概跑了四五十个线程,设备有gui界面、可以进行sip对讲、人脸识别等。
前几天碰到一个很奇怪的现象,在待机界面下或是进行蓝牙开门时(或是一些其他操作,总之没有规律)设备会卡死,期间界面动不了、键盘无响应。大概卡个10分钟左右自动恢复。。在卡住的时候发现cpu使用率还是正常待机时70%左右,但是现象是其他线程都不工作了,该打印的不打印,只有ls、top等系统命令是可以正常使用。
这个问题也是很难复现,几十台设备几天才会有1台出现,不知道如何排查。。

不知道大家有没有好的办法支支招,能有效缩小问题点范围?
设备还有8M剩余内存可在一台跑2.6内核的嵌入式linux设备上(可视对讲门口机),大概有十几个进程,其中自己的应用程序占用1个hicore进程,里面大概跑了四五十个线程,设备有gui界面、可以进行sip对讲、人脸识别等。
前几天碰到一个很奇怪的现象,在待机界面下或是进行蓝牙开门时(或是一些其他操作,总之没有规律)设备会卡死,期间界面动不了、键盘无响应。大概卡个10分钟左右自动恢复。。在卡住的时候发现cpu使用率还是正常待机时70%左右,但是现象是其他线程都不工作了,该打印的不打印,只有ls、top等系统命令是可以正常使用。
这个问题也是很难复现,几十台设备几天才会有1台出现,不知道如何排查。。

不知道大家有没有好的办法支支招,能有效缩小问题点范围?
设备还有8M剩余内存可用,跑GDB貌似也不够了用,跑GDB貌似也不够了

1、Aborted的问题,例如:

./logUtils0322

[UnitTest.cpp]:will init log
[cfgfile.cpp]: logfile open suc
[LogUtils.cpp]:NOTICE OPen configue file SUC
[LogUtils.cpp]:NOTICE suc OpenLogFile()
[LogUtils.cpp]:NOTICE suc Log_Init()
Aborted
这个问题是由于访问内存错误造成的,例如一次时因为循环越界,导致访问界外内存时出现过此种问题。

2、程序卡死的问题,就是程序的进程还在,但是却卡在那里什么都不做,该问题可能也是内存访问越界造成的;另外还可能是多线程中混合使用C和C++的函数 造成,例如:某些嵌入式linux平台对C++支持的不好,这时候如果在多线程中混合使用printf和cout,就会造成此问题

3、segmentation fault的问题也是访问非法内存造成的。

造成上述问题的主要原因就是内存操作引起的,因此在开发过程中,使用指针一定特别留心;
1、申请指针变量时一定将其赋值为NULL;
例如:
Itest* pTest = NULL;
pTest = GetInstance();

2、使用指针之前一定先判断有效性;
例如:
if(NULL != pTest)
pTest->Display();

3、避免重复释放,在释放内存之前一定先判断是否已经为空;
4、释放内存之后一定将指针赋值为NULL;
例如:
if(NULL != pTest)
{
delete pTest;
pTest = NULL;
}

在比较大型的项目中,通常都会使用多线程技术,而且通常是多人合作开发,各方自测OK之后,整合在一起往往会出现一些问题,CPU使用率过高就是其中之一。如何在不熟悉所有模块代码的情况下,快速的定位到具体哪一个线程在消耗CPU,显得很有必要。在X86上,可以借助一些工具进行定位分析,但是在嵌入式系统中,工具就比较匮乏,各命令功能也比较简单,就不好定位。现介绍一种简单通用的办法:

第一步:

获取各个线程的tid,Linux环境下的线程其实就是轻量级的进程,只不过通过top\ps等常用命令一般都查不到具体的线程号tid(指在嵌入式系统中),需要在各个线程实现代码中获取线程ID。

[html] view plain copy
#include

pid_t gettid()

{

return syscall(SYS_gettid);

}

参考自:Linux打印真实pid的方法 http://blog.csdn.net/gaoxuelin/article/details/9718189

第二步:

通过线程ID获得各线程的CPU使用率。

主要是通过分析/proc//task//stat文件获得,pid为程序的PID,tid为程序的各个线程的ID号(就是第一步输出的线程ID),stat文件就是一些调度的基本信息,具体可参阅:Linux proc/pid/task/tid/stat文件详解 http://blog.csdn.net/ctthuangcheng/article/details/18090701

线程比较多的时候一个线程一个线程去分析该文件比较费劲,可通过脚本一次解析完成,参数为进程PID,运行成功会输出该进程的所有线程tid、用户层CPU使用、内核态CPU使用,数值越高表示消耗CPU资源越多。

对于第一点和第三点一半都会导致设备重启,第二点中的嵌入式linux平台对C++支持的不好,如何理解?