Linux 多线程调试(内存占用、死循环、CPU占用率高……)

转载 2015年07月10日 10:53:51

文章出处:http://www.cnblogs.com/cy568searchx/archive/2013/10/28/3391790.html


你的软件在某个时刻停止服务,CPU占用达到100%+,这种问题一个可能的原因是产生了死循环,假设程序某处存在潜在的死循环,并在某种条件下会引发,本文以一个示例来定位出现死循环的位置。
当程序某处存在死循环,通常定位问题及缩小范围的方法是,在可疑的代码处加log,或者注释掉可疑代码,这对于容易重现问题的程序来说还好,但对于“偶尔”才会产生问题程序却很难调试,因为我们很难重现程序故障。本文所述的调试过程正是在这种情况下,假设问题已经出现,我们要求环境保护现场,即出问题的程序还在运行中。

1.我们首先要知道是哪个线程出了问题:
首先查一下出问题进程的pid,例如

ovtsvn@ovtsvn:~/MASS4/src/icdn/src$ ps -ef | grep icdn 
ovtsvn   11065     1 50 11:57 ?        00:00:07 ./icdn 
ovtsvn   11076 10971  0 11:57 pts/2    00:00:00 grep
ovtsvn@ovtsvn:~/MASS4/src/icdn/src$
ovtsvn@ovtsvn:~/MASS4/src/icdn/src$ 

然后top命令查看线程信息:
top -H -p 11065

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                 
11073 ovtsvn    25   0  325m 3980 2236 R  100  0.4   1:40.84 icdn                                                                    
11065 ovtsvn    18   0  325m 3980 2236 S    0  0.4   0:00.01 icdn                                                                    
11066 ovtsvn    18   0  325m 3980 2236 S    0  0.4   0:00.00 icdn                                                                    
11067 ovtsvn    15   0  325m 3980 2236 S    0  0.4   0:00.00 icdn                                                                    
11068 ovtsvn    15   0  325m 3980 2236 S    0  0.4   0:00.00 icdn                                                                    
11069 ovtsvn 180 325m 39802236 S 00.40:00.00 icdn 
11070 ovtsvn 180 325m 39802236 S 00.40:00.00 icdn 
11071 ovtsvn 220 325m 39802236 S 00.40:00.00 icdn 
11072 ovtsvn 150 325m 39802236 R 00.40:00.00 icdn
 

从上面可以看出,出问题线程PID为11073

2.接下来,我们用gdb来attach目标进程
执行: gdb icdn 11065
在gdb中,列出线程状态:

(gdb) info threads   
9 Thread 47056948181264 (LWP 11066)  0x00002acc4a3dec91 in nanosleep () from /lib/libc.so.6   
8 Thread 47056956573968 (LWP 11067)  0x00002acc4a406fc2 in select () from /lib/libc.so.6   
7 Thread 47056964966672 (LWP 11068)  0x00002acc4a3dec91 in nanosleep () from /lib/libc.so.6  
 6 Thread 47056973359376 (LWP 11069)  0x00002acc4a3dec91 in nanosleep () from /lib/libc.so.6   
5 Thread 47056981752080 (LWP 11070)  0x00002acc4a3dec91 in nanosleep () from /lib/libc.so.6   
4 Thread 47056990144784 (LWP 11071)  0x00002acc4a40e63c in recvfrom () from /lib/libc.so.6   
3 Thread 47057194060048 (LWP 11072)  0x00002acc4a406fc2 in select () from /lib/libc.so.6   
2 Thread 47057226893584 (LWP 11073)  CSendFile::SendFile (this=0x2acc5d4aff40, pathname=@0x2acc5d4afee0    at ../src/csendfile.cpp:101   
1 Thread 47056939784832 (LWP 11065)  0x00002acc4a3dec91 in nanosleep () from /lib/libc.so.6 (gdb) 


gdb已经列出了各线程正在执行的函数,我们需要更多信息,记住11073对应的行首标号,这是gdb为线程分配的id,这里为2,然后执行切换:

(gdb) thread 2 
[Switching to thread 2 (Thread 47057226893584 (LWP 11073))]#0  CSendFile::SendFile (this=0x2acc5d4aff40, pathname=@0x2acc5d4afee0    at ../src/csendfile.cpp:101 101             while(1
(gdb) 

bt一下:

(gdb) bt 
#0  CSendFile::SendFile (this=0x2acc5d4aff40, pathname=@0x2acc5d4afee0) at ../src/csendfile.cpp:101 
#1  0x000000000040592e in CIcdn::TaskThread (pParam=0x7fff617eafe0) at ../src/cicdn.cpp:128 
#2  0x00002acc4a90b73a in start_thread () from /lib/libpthread.so.0 
#3  0x00002acc4a40d6dd in clone () from /lib/libc.so.6 
#4  0x0000000000000000 in ?? ()


来看一下101行的代码:

(gdb) l 
96      } 
97 
98      int CSendFile::SendFile(const string& pathname) 
99      {
100             int n;
101             while(1)
102             {
103                     n++;
104             }
105             //read file and send 

现在我们定位到了出问题的代码位置,这里的循环只用来演示的。 
最后别忘了detach()

调试完指定进程后,可以运行detach命令来让GDB释放该进程,该进程得以继续运行。当回车时,detach不会重复。当执行完detach后,进程和GDB不再相关,GDB可以attach其他进程。


Firefox占用CPU、内存太高解决办法

CPU解决:首先解决CPU占用率高,打开网页停顿的问题。很简单,在“工具”/“选项”/“内容”里,找到“启用Java“这一项,去掉前面的勾,然后确认,重启即可解决问题内存解决: 为Firefox设置快...
  • killua_hzl
  • killua_hzl
  • 2009年10月06日 08:06
  • 3776

死循环导致apk的 cpu占用率过高

(1)分析: $ busybox top $ 1 (2) 线程中如果一直while的话,cpu一直霸用不能闲置 while(true){ } (3)处理 while(true){ s...
  • kg_second
  • kg_second
  • 2016年03月17日 14:20
  • 922

解决polkit-gnome-manage CPU占用率高的现象

刚才笔记本的风扇突然狂转不止,top一下发现polkit-gnome-manage的CPU占用率在50%以上,google了一下,找到了解决方法 在 /etc/rc.conf 添加polkit_ena...
  • wag2765
  • wag2765
  • 2016年01月25日 16:38
  • 1309

Linux Cpu占用高调试方法

Linux Cpu占用高调试方法
  • qilin001cs
  • qilin001cs
  • 2016年06月01日 08:56
  • 4045

为什么死循环占用CPU高

文章出处:http://bbs.chinaunix.net/thread-1613560-1-1.html   为什么死循环占用CPU高 一个进程如果是死循环,那么占有的CPU会很高,可是操作系统时间...
  • ixidof
  • ixidof
  • 2011年08月08日 21:57
  • 8649

解决WIN10“系统和压缩内存”“ntoskrnl.exe”系统空闲时占用大量CPU

前些天装了WIN10,感觉,一般般,最近发现个怪现象,一旦机器有空闲一会,那个“系统和压缩内存”进程就会占用我20%的CPU不知道干嘛。百度一下,国内都在讨论这个进程对内存的消耗,我机器16G内存不存...
  • wadqse123
  • wadqse123
  • 2016年03月09日 14:40
  • 26299

多线程占用cpu过高

线程中要有sleep操作,释放控制权,否则其他线程得不到CPU的控制权,同时当空线程执行时,容易CPU占用过高。...
  • iamherego
  • iamherego
  • 2016年11月09日 19:07
  • 1095

linux问题排查 - 高cpu占用率的进程和线程

1.简介           一个程序,完成它预设的功能,并不能说明它是一个优良的程序。好的程序,应该是对资源的合理利用,亦或是 用更少的资源(使用合理的算法),实现更多有效的产出。       影响...
  • hrn1216
  • hrn1216
  • 2016年05月16日 17:31
  • 35905

嵌入式 如何定位死循环或高CPU使用率(linux)

如何定位死循环或高CPU使用率(linux)  确定是CPU过高 使用top观察是否存在CPU使用率过高现象 找出线程 对CPU使用率过高的进程的所有线程进行排序 ps H -e -...
  • skdkjxy
  • skdkjxy
  • 2014年07月13日 18:18
  • 1545

Java 占用CPU使用率很高的分析

前几天在测试服务器上发现Java进程的CPU使用率暴高,为了分析解决该问题,把过程记录如下: 1. 先找到Java的进程号 Linux下: 用top命令查看所有进程,可以明显看到Java的,因为CPU...
  • xeseo
  • xeseo
  • 2013年09月22日 10:44
  • 11042
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux 多线程调试(内存占用、死循环、CPU占用率高……)
举报原因:
原因补充:

(最多只允许输入30个字)