調(diào)試陷入死循環(huán)程序的方法

概述

應(yīng)用程序陷入死循環(huán)后,界面可能不會(huì)有任何輸出掉冶,所有的業(yè)務(wù)也不通真竖,不易定位。

陷入死循環(huán)的程序占用的cpu使用率較高厌小,通郴止玻可以通過(guò)使用top命令看出來(lái)。

對(duì)于多線程的程序璧亚,需要耐心調(diào)試讨韭,本文給出筆者近期使用的方法。

調(diào)試步驟

測(cè)試程序

編寫(xiě)一個(gè)多線程進(jìn)入死循環(huán)的測(cè)試程序癣蟋,如下:

#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 = %u\n", ntid[i]);
        }
    }
    while(1) {
        pause();
    }

    return 0;
}

編譯:gcc -g while_test.c -pthread

該程序運(yùn)行后進(jìn)入死循環(huán)透硝,下面分析調(diào)試方法。

確定陷入死循環(huán)的程序

  • 程序運(yùn)行后會(huì)打印各id號(hào)疯搅,然后無(wú)任何輸出濒生,程序陷入了死循環(huán)

  • ps確認(rèn)程序仍在運(yùn)行,ps也可以查看進(jìn)程狀態(tài)

  • ps -T 查看進(jìn)程中包含的線程

-> % 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 查看各線程的運(yùn)行時(shí)間秉撇,可以輔助確認(rèn)處于死循環(huán)的線程
-> % 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查看進(jìn)程cpu使用率
  • top -H 查看各線程的使用率
  • top界面下按1查看各個(gè)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  

調(diào)試程序死在何處

使用gdb調(diào)試程序:

  • 使用attach pid 進(jìn)入之前查看到的進(jìn)程
  • 使用info threads 查看線程信息甜攀,可以看到四個(gè)線程的運(yùn)行位置
  • 使用thread 序號(hào) 進(jìn)入指定序號(hào)的線程秋泄,打印出運(yùn)行的位置
  • 使用bt 打印棧信息,查看函數(shù)調(diào)用關(guān)系
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

結(jié)論

對(duì)于陷入死循環(huán)的程序规阀,服務(wù)器一般會(huì)頻繁地散熱恒序,在多線程業(yè)務(wù)復(fù)雜的程序中有可能出現(xiàn)。

開(kāi)發(fā)人員在編程時(shí)需要考慮全面細(xì)致谁撼,盡量注意到可能的異常歧胁,很多死循環(huán)是因?yàn)闆](méi)有預(yù)料到的異常引入的。

對(duì)于陷入死循環(huán)的程序厉碟,穩(wěn)位步驟喊巍,逐步調(diào)試,并不難定位原因箍鼓。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末崭参,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子款咖,更是在濱河造成了極大的恐慌何暮,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件铐殃,死亡現(xiàn)場(chǎng)離奇詭異海洼,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)富腊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門(mén)坏逢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人赘被,你說(shuō)我怎么就攤上這事是整。” “怎么了帘腹?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,871評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵贰盗,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我阳欲,道長(zhǎng),這世上最難降的妖魔是什么陋率? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,963評(píng)論 1 295
  • 正文 為了忘掉前任球化,我火速辦了婚禮,結(jié)果婚禮上瓦糟,老公的妹妹穿的比我還像新娘筒愚。我一直安慰自己,他們只是感情好菩浙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布巢掺。 她就那樣靜靜地躺著句伶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪陆淀。 梳的紋絲不亂的頭發(fā)上考余,一...
    開(kāi)封第一講書(shū)人閱讀 51,763評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音轧苫,去河邊找鬼楚堤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛含懊,可吹牛的內(nèi)容都是我干的身冬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼岔乔,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼酥筝!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起雏门,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤樱哼,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后剿配,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體搅幅,經(jīng)...
    沈念sama閱讀 45,850評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評(píng)論 3 338
  • 正文 我和宋清朗相戀三年呼胚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了茄唐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蝇更,死狀恐怖沪编,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情年扩,我是刑警寧澤蚁廓,帶...
    沈念sama閱讀 35,823評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站厨幻,受9級(jí)特大地震影響相嵌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜况脆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評(píng)論 3 331
  • 文/蒙蒙 一饭宾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧格了,春花似錦看铆、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,026評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)否淤。三九已至,卻和暖如春棠隐,著一層夾襖步出監(jiān)牢的瞬間石抡,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,150評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工宵荒, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留汁雷,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,415評(píng)論 3 373
  • 正文 我出身青樓报咳,卻偏偏與公主長(zhǎng)得像侠讯,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子暑刃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容