摘自http://www.cppblog.com/elva/archive/2010/08/02/121943.html
Linux下,多线程程序死循环问题调试
当你的软件在某个时刻停止服务,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 icdn
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 18 0 325m 3980 2236 S 0 0.4 0:00.00 icdn
11070 ovtsvn 18 0 325m 3980 2236 S 0 0.4 0:00.00 icdn
11071 ovtsvn 22 0 325m 3980 2236 S 0 0.4 0:00.00 icdn
11072 ovtsvn 15 0 325m 3980 2236 R 0 0.4 0: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
分享到:
相关推荐
Linux下基于多线程的服务器程序设计.pdf
linux下多线程编程linux下多线程编程linux下多线程编程linux下多线程编程linux下多线程编程
用GDB调试多线程程序 方便在linux下调试多线程程序
基于Linux的python多线程爬虫程序设计.pdf
linux下多线程程序设计,好资料,学习了
gdb调试多线程程序总结 gdb调试多线程程序总结
linux下多线程是想操作系统的经典生产者和消费者模拟实验。用C语言编写,gcc能够编译。而且含有makefile文件的解释。
linux编程 多线程编程 网络套节字编程
Linux系统下的多线程编程入门.pdf Linux系统下的多线程编程入门.pdf Linux系统下的多线程编程入门.pdf Linux系统下的多线程编程入门.pdf Linux系统下的多线程编程入门.pdf Linux系统下的多线程编程入门.pdf Linux...
Linux多线程Linux多线程Linux多线程Linux多线程Linux多线程Linux多线程Linux多线程
linux下多线程查询端口程序源码,已经经过调试,可以查询1-5个IP地址的端口服务。
linux下多线程实现矩阵乘法,可以对操作系统的线程有更多理解
Linux下多线程计算圆周率 C语言 //实现一个用多线程计算 π(圆周率)的程序。 #include #include #include #include #define N 50000//设定计算次数 #define NUM 2//设定线程数,经过反复实验,在装有1个双核...
Linux下的多线程编程.pdf
主要介绍了Java中一个线程执行死循环有什么后果,当一个线程在执行死循环时会影响另外一个线程吗,下面为大家揭晓
编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a。顺便说一下,Linux下pthread的实现是通过系统调用clone()来实现的。clone()是Linux所特有的系统调用,它的使用方式类似fork...
嵌入式 Linux 应用程序开发 第9章多线程编程 华清远见
使用多线程程序模拟实现单生产者/多消费者问题。 要求“生产者”随机产生一个整数,“消费者 1”将这个整数加 1 后输出,“消 费者 2”将这个整数加 2 后输出,“消费者 3”将这个整数加 3 后输出,“消 费者 4”将...
基于linux下的c/c++程序,多线程,断点续传功能没有实现, 可传输大于2G的文件。 设计思想:预先分配的N个缓冲区形成类似循环队列。 【1】预先分配N个缓冲区,多线程方式对缓冲区进行读写互斥,有类似生产者消费者的...
LINUX下多线程编程,PDF文档,详细介绍