概述
概述
应用程序陷入死循环后,界面可能不会有任何输出,所有的业务也不通,不易定位。
陷入死循环的程序占用的cpu使用率较高,通常可以通过使用top命令看出来。
对于多线程的程序,需要耐心调试,本文给出笔者近期使用的方法。
调试步骤
测试程序
编写一个多线程进入死循环的测试程序,如下:
#include <stdio.h>
#include <pthread.h>
#define MAX_THREAD 4
static void dead_loop(void)
{
while(1) {
continue;
}
}
int main(void)
{
int i = 0;
pthread_t ntid[MAX_THREAD];
// dead_loop();
for (i = 0; i < 4; i++) {
if (pthread_create(&ntid[i], NULL, (void *)dead_loop, NULL) == 0) {
printf("pthread id = %un", ntid[i]);
}
}
while(1) {
pause();
}
return 0;
}
编译:gcc -g while_test.c -pthread
该程序运行后进入死循环,下面分析调试方法。
确定陷入死循环的程序
程序运行后会打印各id号,然后无任何输出,程序陷入了死循环
ps确认程序仍在运行,ps也可以查看进程状态
- ps -T 查看进程中包含的线程
-> % ps -eT | grep a.out
10703 10703 pts/0 00:00:00 a.out
10703 10704 pts/0 00:00:39 a.out
10703 10705 pts/0 00:00:40 a.out
10703 10706 pts/0 00:00:41 a.out
10703 10707 pts/0 00:00:40 a.out
- ps -eL 查看各线程的运行时间,可以辅助确认处于死循环的线程
-> % ps -eL | grep a.out
10703 10703 pts/0 00:00:00 a.out
10703 10704 pts/0 00:01:33 a.out
10703 10705 pts/0 00:01:34 a.out
10703 10706 pts/0 00:01:31 a.out
10703 10707 pts/0 00:01:34 a.out
- top查看进程cpu使用率
- top -H 查看各线程的使用率
- top界面下按1查看各个cpu的占用率
-> % top -H
top - 21:47:24 up 6:18, 3 users, load average: 0.90, 0.64, 0.60
Threads: 402 total, 5 running, 396 sleeping, 0 stopped, 1 zombie
%Cpu0 :100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 99.7 us, 0.3 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu2 : 99.7 us, 0.3 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 :100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem: 1024256 total, 1002628 used, 21628 free, 101592 buffers
KiB Swap: 1046524 total, 4456 used, 1042068 free. 342212 cached Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
10796 yao 20 0 35068 608 544 R 99.9 0.1 0:15.59 a.out
10797 yao 20 0 35068 608 544 R 99.9 0.1 0:15.68 a.out
10794 yao 20 0 35068 608 544 R 99.3 0.1 0:15.66 a.out
10795 yao 20 0 35068 608 544 R 99.3 0.1 0:15.50 a.out
调试程序死在何处
使用gdb调试程序:
- 使用attach pid 进入之前查看到的进程
- 使用info threads 查看线程信息,可以看到四个线程的运行位置
- 使用thread 序号 进入指定序号的线程,打印出运行的位置
- 使用bt 打印栈信息,查看函数调用关系
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) attach 10848
Attaching to process 10848
Reading symbols from /home/yao/work/util/a.out...done.
Reading symbols from /lib/i386-linux-gnu/libpthread.so.0...Reading symbols from /usr/lib/debug//lib/i386-linux-gnu/libpthread-2.19.so...done.
done.
[New LWP 10852]
[New LWP 10851]
[New LWP 10850]
[New LWP 10849]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/i386-linux-gnu/libthread_db.so.1".
Loaded symbols for /lib/i386-linux-gnu/libpthread.so.0
Reading symbols from /lib/i386-linux-gnu/libc.so.6...Reading symbols from /usr/lib/debug//lib/i386-linux-gnu/libc-2.19.so...done.
done.
Loaded symbols for /lib/i386-linux-gnu/libc.so.6
Reading symbols from /lib/ld-linux.so.2...Reading symbols from /usr/lib/debug//lib/i386-linux-gnu/ld-2.19.so...done.
done.
Loaded symbols for /lib/ld-linux.so.2
0xb7718cb0 in ?? ()
(gdb) info threads
Id Target Id Frame
5 Thread 0xb7530b40 (LWP 10849) "a.out" dead_loop () at while_test.c:10
4 Thread 0xb6d2fb40 (LWP 10850) "a.out" dead_loop () at while_test.c:10
3 Thread 0xb652eb40 (LWP 10851) "a.out" dead_loop () at while_test.c:10
2 Thread 0xb5d2db40 (LWP 10852) "a.out" dead_loop () at while_test.c:10
* 1 Thread 0xb7531700 (LWP 10848) "a.out" 0xb7718cb0 in ?? ()
(gdb) bt
#0 0xb7718cb0 in ?? ()
#1 0xb754ca83 in __libc_start_main (main=0x8048552 <main>, argc=1, argv=0xbf999c34, init=0x80485d0 <__libc_csu_init>,
fini=0x8048640 <__libc_csu_fini>, rtld_fini=0xb7729180 <_dl_fini>, stack_end=0xbf999c2c) at libc-start.c:287
#2 0x08048471 in _start ()
(gdb) thread 2
[Switching to thread 2 (Thread 0xb5d2db40 (LWP 10852))]
#0 dead_loop () at while_test.c:10
10 }
(gdb) bt
#0 dead_loop () at while_test.c:10
#1 0xb76e7f70 in start_thread (arg=0xb5d2db40) at pthread_create.c:312
#2 0xb761ebee in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:129
结论
对于陷入死循环的程序,服务器一般会频繁地散热,在多线程业务复杂的程序中有可能出现。
开发人员在编程时需要考虑全面细致,尽量注意到可能的异常,很多死循环是因为没有预料到的异常引入的。
对于陷入死循环的程序,稳位步骤,逐步调试,并不难定位原因。
最后
以上就是欢喜口红为你收集整理的调试陷入死循环程序的方法的全部内容,希望文章能够帮你解决调试陷入死循环程序的方法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复