之前分享過(guò)一篇Linux開(kāi)發(fā)coredump文件分析實(shí)戰(zhàn)分享 ,今天再來(lái)分享一篇實(shí)戰(zhàn)文章。
在我們嵌入式linux開(kāi)發(fā)過(guò)程中,開(kāi)發(fā)過(guò)程中我們經(jīng)常會(huì)使用多進(jìn)程、多線程開(kāi)發(fā)。那么多線程使用過(guò)程中,我們大概率會(huì)遇到某線程長(zhǎng)時(shí)間占用cpu,導(dǎo)致設(shè)備執(zhí)行異常。
通常只有四五個(gè)線程,我們可以通過(guò)一個(gè)個(gè)線程調(diào)試捕捉到異常線程,如果你開(kāi)發(fā)的設(shè)備上面運(yùn)行了大概三四十個(gè)線程,我們一下子不好看到對(duì)應(yīng)哪個(gè)線程出問(wèn)題,也不好使用列舉法進(jìn)行搜索,這個(gè)時(shí)候我們需要配合一些工具進(jìn)行監(jiān)控以及檢查我們執(zhí)行的進(jìn)程下面的線程。下面我就給大家介紹一下我自己工作中實(shí)際遇到的例子。
歡迎關(guān)注微信公眾號(hào):羽林君,或者添加作者個(gè)人微信:become_me
情節(jié)介紹:
在工作中,我遇到這樣一個(gè)問(wèn)題,我的設(shè)備跑機(jī)的時(shí)候發(fā)現(xiàn),機(jī)器運(yùn)行某些狀態(tài)時(shí)候有些怪異,對(duì)于某些機(jī)制的處理響應(yīng)不夠及時(shí),最后top檢查,發(fā)現(xiàn)是我運(yùn)行的某個(gè)進(jìn)程中的某幾個(gè)線程運(yùn)行cpu占有率很高,導(dǎo)致其他的一些線程無(wú)法及時(shí)運(yùn)行。
找到問(wèn)題了,接下來(lái)我們就開(kāi)始找對(duì)應(yīng)的線程然后進(jìn)行修改,前文提到,進(jìn)程里面有一兩個(gè)線程還好說(shuō),我們可以通過(guò)一些比較基礎(chǔ)的方法,一個(gè)個(gè)線程進(jìn)行l(wèi)og或者其他手段的信息輸出,但是如果我們遇到單個(gè)進(jìn)程里面有很多線程的時(shí)候,我們?nèi)绾螜z查呢?
初步列一個(gè)使用的工具大綱:ps 組合命令、top組合命令、pstack、strace、ltrace、gdb attach <pid>實(shí)時(shí)調(diào)試 、 ?kill <sig> <pid>、coredump文件查看線程堆棧
以上就是我使用到的一些命令和操作,接下來(lái)一一給大家進(jìn)行分析和介紹:
首先給大家介紹每個(gè)工具和命令詳細(xì)介紹,再用自己的一個(gè)小例子把這些工具進(jìn)行組合使用說(shuō)明。
工具和組合命令詳細(xì)介紹
首先給詳細(xì)的介紹一下這些工具說(shuō)明書(shū):
ps 的選項(xiàng)參數(shù)介紹:
ps命令大家在linux使用應(yīng)該是很熟悉的,ps是Process Status的縮寫(xiě),用來(lái)列出系統(tǒng)中當(dāng)前運(yùn)行的進(jìn)程。使用該命令可以確定有哪些進(jìn)程正在運(yùn)行和運(yùn)行的狀態(tài)、進(jìn)程是否結(jié)束、進(jìn)程有沒(méi)有僵死、哪些進(jìn)程占用了過(guò)多的資源等等。ps命令所列出的進(jìn)行是當(dāng)前進(jìn)程的快照,也就是并不是動(dòng)態(tài)的,而是執(zhí)行該命令時(shí)那一時(shí)刻進(jìn)行的狀態(tài)。
ps?的參數(shù)非常多,?在此僅列出幾個(gè)常用的參數(shù)并大略介紹含義
-A?列出所有的進(jìn)程
-w?顯示加寬可以顯示較多的資訊
-au?顯示較詳細(xì)的資訊
-aux?顯示所有包含其他使用者的行程
我一般都是使用 ps -aux進(jìn)行查看后臺(tái)運(yùn)行的進(jìn)程pid
下面再進(jìn)行補(bǔ)充一下今天要使用到的ps組合命令
查看進(jìn)程對(duì)應(yīng)的線程
ps?-T?-p?472?(472?此處為真實(shí)進(jìn)程的pid大家自行替換)
第一行是對(duì)應(yīng)的進(jìn)程ID,第二行是對(duì)應(yīng)的線程ID
查看進(jìn)程對(duì)應(yīng)線程的執(zhí)行時(shí)間
ps?-eLo?pid,lwp,pcpu?|grep?1780(1780?此處為真實(shí)進(jìn)程的pid大家自行替換)
第一行是進(jìn)程pid,第二行是進(jìn)程里面線程對(duì)應(yīng)的pid,第三行是該線程執(zhí)行ms時(shí)間,通過(guò)線程執(zhí)行時(shí)間長(zhǎng)度,我們配合該線程的堆棧信息,線程頻繁執(zhí)行IO操作或者線程頻繁執(zhí)行的庫(kù)函數(shù)來(lái)判斷該線程是否錯(cuò)誤占用cpu資源。
top組合命令介紹:
top命令也是大家熟悉的一個(gè)命令,可以顯示當(dāng)前系統(tǒng)正在執(zhí)行的進(jìn)程的相關(guān)信息,包括進(jìn)程ID、內(nèi)存占用率、CPU占用率等。同時(shí)也可以對(duì)指定進(jìn)程發(fā)送一個(gè)信號(hào)。
-b?批處理
-c?顯示完整的信息
-I?忽略失效過(guò)程
-s?保密模式
-S?累積模式
-i<時(shí)間>?設(shè)置間隔時(shí)間
-u<用戶(hù)名>?指定用戶(hù)名
-p<進(jìn)程號(hào)>?指定進(jìn)程
-n<次數(shù)>?循環(huán)顯示的次數(shù)
首先我們一般會(huì)直接使用top命令,查看進(jìn)程信息,這里做一下多描述,因?yàn)楹罄m(xù)使用strace工具還是使用ltrace工具,是從top命令的cpu信息區(qū)進(jìn)行確定我們使用具體工具。
test@test:~#?top
top?-?02:32:07?up?17?min,??2?users,??load?average:?3.17,?3.26,?2.17
Tasks:?165?total,???3?running,?162?sleeping,???0?stopped,???0?zombie
%Cpu(s):?31.3?us,??7.0?sy,??0.0?ni,?60.9?id,??0.0?wa,??0.0?hi,??0.9?si,??0.0?st
MiB?Mem?:???3845.3?total,???3424.3?free,????240.9?used,????180.1?buff/cache
MiB?Swap:??????0.0?total,??????0.0?free,??????0.0?used.???3566.7?avail?Mem
??PID?USER??????PR??NI????VIRT????RES????SHR?S??%CPU??%MEM?????TIME+?COMMAND
??461?root?????-96?-20?2432536??58472??18888?S?176.5???1.5??18:15.07?ex
??375?root??????-2???0???????0??????0??????0?S???5.9???0.0???0:04.23?RTW_RECV_THREAD
??430?root??????20???0??682204??22536???6880?S???5.9???0.6???0:55.69?python
16913?root??????20???0???????0??????0??????0?S???5.9???0.0???0:02.46?kworker/u12:0
22219?root??????20???0????3300???2100???1628?R???5.9???0.1???0:00.02?top
????1?root??????20???0????1892????620????556?S???0.0???0.0???0:00.41?init
????2?root??????20???0???????0??????0??????0?S???0.0???0.0???0:00.01?kthreadd
????3?root??????20???0???????0??????0??????0?S???0.0???0.0???0:00.14?ksoftirqd/0
????5?root???????0?-20???????0??????0??????0?S???0.0???0.0???0:00.00?kworker/0:0H
????7?root??????20???0???????0??????0??????0?R???0.0???0.0???0:02.24?rcu_sched
????8?root??????20???0???????0??????0??????0?S???0.0???0.0???0:00.00?rcu_bh
????9?root??????rt???0???????0??????0??????0?S???0.0???0.0???0:00.16?migration/0
???10?root??????rt???0???????0??????0??????0?S???0.0???0.0???0:00.00?watchdog/0
top顯示的統(tǒng)計(jì)信息:
top顯示信息前五行是當(dāng)前系統(tǒng)情況整體的統(tǒng)計(jì)信息區(qū)。這部分統(tǒng)計(jì)信息的解釋參考文章《top命令》:
第一行,任務(wù)隊(duì)列信息,同 uptime 命令的執(zhí)行結(jié)果
test@test:~#?uptime
?13:46:08?up??1:04,??1?user,??load?average:?0.00,?0.00,?0.00
具體參數(shù)說(shuō)明情況如下:
02:32:07?—?當(dāng)前系統(tǒng)時(shí)間
up?17?min,??—?系統(tǒng)已經(jīng)運(yùn)行了17分鐘
2?users?—?當(dāng)前有2個(gè)用戶(hù)終端登錄系統(tǒng)
load average: 3.17, 3.26, 2.17— load average后面的三個(gè)數(shù)分別是1分鐘、5分鐘、15分鐘的負(fù)載情況。
load average數(shù)據(jù)是每隔5秒鐘檢查一次活躍的進(jìn)程數(shù),然后按特定算法計(jì)算出的數(shù)值。如果這個(gè)數(shù)除以邏輯CPU的數(shù)量,結(jié)果高于5的時(shí)候就表明系統(tǒng)在超負(fù)荷運(yùn)轉(zhuǎn)了。
第二行,Tasks — 任務(wù)(進(jìn)程),具體信息說(shuō)明如下:
系統(tǒng)現(xiàn)在共有165個(gè)進(jìn)程,其中處于運(yùn)行中的有3個(gè),162個(gè)在休眠(sleep),stoped狀態(tài)的有0個(gè),zombie狀態(tài)(僵尸)的有0個(gè)。
第三行,cpu狀態(tài)信息,具體屬性說(shuō)明如下:
31.3 us —?用戶(hù)空間占用CPU的百分比。
7.0? sy —?內(nèi)核空間占用CPU的百分比。
0.0??ni?—?改變過(guò)優(yōu)先級(jí)的進(jìn)程占用CPU的百分比
60.9??id?—?空閑CPU百分比
0.0?wa?—?IO等待占用CPU的百分比
0.0?hi?—?硬中斷(Hardware?IRQ)占用CPU的百分比
0.9?si?—?軟中斷(Software?Interrupts)占用CPU的百分比
0.0?st?虛擬機(jī)管理程序?yàn)榱硪粋€(gè)處理器(從虛擬機(jī)中竊?。┓?wù)時(shí),虛擬cpu進(jìn)行非自愿等待所花費(fèi)的時(shí)間
第四行,內(nèi)存狀態(tài),具體信息如下:
3845.3?total?—?物理內(nèi)存總量(3.8GB)
3424.3?free?—?空閑內(nèi)存總量(3.2GB)
240.9?used?—?使用中的內(nèi)存總量(240.9MB)
180.1?buff/cache?—?緩存的內(nèi)存量?(180M)
第五行,swap交換分區(qū)信息,具體信息說(shuō)明如下:
0.0?total?—?交換區(qū)總量(0.0?GB)
0.0?free?—?空閑交換區(qū)總量(0MB)
0.0?used?—?使用的交換區(qū)總量(0MB)
3566.7?avail?Mem?—?可使用緩沖的交換區(qū)總量(3.5GB)
第六行,空行。
第七行以下:各進(jìn)程(任務(wù))的狀態(tài)監(jiān)控,項(xiàng)目列信息說(shuō)明如下:
PID?—?進(jìn)程id
USER?—?進(jìn)程所有者
PR?—?進(jìn)程優(yōu)先級(jí)
NI — nice值。負(fù)值表示高優(yōu)先級(jí),正值表示低優(yōu)先級(jí)
VIRT —?進(jìn)程使用的虛擬內(nèi)存總量,單位kb。VIRT=SWAP+RES
RES —?進(jìn)程使用的、未被換出的物理內(nèi)存大小,單位kb。RES=CODE+DATA
SHR?—?共享內(nèi)存大小,單位kb
S —?進(jìn)程狀態(tài)。D=不可中斷的睡眠狀態(tài) R=運(yùn)行 S=睡眠 T=跟蹤/停止 Z=僵尸進(jìn)程
%CPU?—?上次更新到現(xiàn)在的CPU時(shí)間占用百分比
%MEM?—?進(jìn)程使用的物理內(nèi)存百分比
TIME+?—?進(jìn)程使用的CPU時(shí)間總計(jì),單位1/100秒
COMMAND?—?進(jìn)程名稱(chēng)(命令名/命令行)
這是top的常規(guī)使用得到的信息,我們一般進(jìn)行組合使用命令,我一般使用,
top?-Hp?461(461?此處為真實(shí)進(jìn)程的pid大家自行替換)
通過(guò)-Hp命令,我可以查看指定進(jìn)程的線程
其中在統(tǒng)計(jì)信息的第三行中,可以看到cpu占用率主要是用戶(hù)態(tài)。
那么我們應(yīng)該最好使用ltrace進(jìn)行用戶(hù)態(tài)庫(kù)函數(shù)的調(diào)用查詢(xún)。當(dāng)然strace也可以,但是由于內(nèi)核使用占據(jù)cpu使用率不高,你追蹤到的IO操作應(yīng)該遠(yuǎn)少于用戶(hù)態(tài)庫(kù)函數(shù)調(diào)用。
pstack 的選項(xiàng)參數(shù)介紹:
pstack 是 Linux 系統(tǒng)下的一個(gè)命令行工具,此命令可以顯示指定進(jìn)程每個(gè)線程的堆棧快照,便于排查程序異常和性能評(píng)估,此命令允許使用的唯一選項(xiàng)是要檢查的進(jìn)程的 PID。要是要使用這個(gè)包大家需要在所使用的linux lib和斌目錄里面增加該工具。
示例
sudo?pstack?16634(該pid為我自己測(cè)試電腦對(duì)應(yīng)的進(jìn)程?大家使用時(shí)候可以自行替換成自己對(duì)應(yīng)的pid)
可以在一段時(shí)間內(nèi),多執(zhí)行幾次pstack,若發(fā)現(xiàn)代碼??偸峭T谕粋€(gè)位置,
那個(gè)位置就需要重點(diǎn)關(guān)注,很可能就是出問(wèn)題的地方;
ltrace 的選項(xiàng)參數(shù)介紹:
ltrace能夠跟蹤進(jìn)程的庫(kù)函數(shù)調(diào)用,它會(huì)顯現(xiàn)出調(diào)用了哪個(gè)庫(kù)函數(shù),而strace則是跟蹤進(jìn)程的每個(gè)系統(tǒng)調(diào)用。ltrace跟蹤進(jìn)程調(diào)用庫(kù)函數(shù)參數(shù)選項(xiàng)有什么?
ltrace 的選項(xiàng)參數(shù)介紹:
-c 統(tǒng)計(jì)庫(kù)函數(shù)每次調(diào)用的時(shí)間,最后程序退出時(shí)打印摘要。
-C 解碼低級(jí)別名稱(chēng)(內(nèi)核級(jí))為用戶(hù)級(jí)名稱(chēng)。
-d 打印調(diào)試信息。
-e expr 輸出過(guò)濾器,通過(guò)表達(dá)式,可以過(guò)濾掉你不想要的輸出。
-e?printf?表示只查看printf函數(shù)調(diào)。
-e!printf?表示查看除printf函數(shù)以外的所有函數(shù)調(diào)用。
-f 跟蹤子進(jìn)程。
-o flename 將ltrace的輸出寫(xiě)入文件filename。
-p pid 指定要跟蹤的進(jìn)程pid。
-r 輸出每一個(gè)調(diào)用的相對(duì)時(shí)間。
-S 顯示系統(tǒng)調(diào)用。
-t 在輸出中的每一行前加上時(shí)間信息。
-tt 在輸出中的每一行前加上時(shí)間信息,精確到微秒。
-ttt 在輸出中的每一行前加上時(shí)間信息,精確到微秒,而且時(shí)間表示為UNIX時(shí)間戳。
-T 顯示每次調(diào)用所花費(fèi)的時(shí)間。
strace 的選項(xiàng)參數(shù)介紹:
strace常用來(lái)跟蹤進(jìn)程執(zhí)行時(shí)的系統(tǒng)調(diào)用和所接收的信號(hào)。在Linux世界,進(jìn)程不能直接訪問(wèn)硬件設(shè)備,當(dāng)進(jìn)程需要訪問(wèn)硬件設(shè)備(比如讀取磁盤(pán)文件,接收網(wǎng)絡(luò)數(shù)據(jù)等等)時(shí),必須由用戶(hù)態(tài)模式切換至內(nèi)核態(tài)模式,通過(guò)系統(tǒng)調(diào)用訪問(wèn)硬件設(shè)備。strace可以跟蹤到一個(gè)進(jìn)程產(chǎn)生的系統(tǒng)調(diào)用,包括參數(shù),返回值,執(zhí)行消耗的時(shí)間。
-f?跟蹤目標(biāo)進(jìn)程,以及目標(biāo)進(jìn)程創(chuàng)建的所有子進(jìn)程
-t?在輸出中的每一行前加上時(shí)間信息(-tt?表示微秒級(jí))
-T?顯示每個(gè)系統(tǒng)調(diào)用所耗的時(shí)間
通過(guò)觀察系統(tǒng)調(diào)用我們可以確認(rèn)當(dāng)前程序的行為,分析其消耗的時(shí)間、返回值是否正常??梢赃^(guò)濾指定的線程號(hào),確認(rèn)當(dāng)前線程的行為是否符合預(yù)期,如果執(zhí)行命令后完全沒(méi)有輸出,那么可以懷疑是否由于網(wǎng)絡(luò)、IO等原因?qū)е伦枞?,或程序產(chǎn)生死鎖。
pstree 的選項(xiàng)參數(shù)介紹:
命令將所有進(jìn)程以樹(shù)狀圖顯示,樹(shù)狀圖將會(huì)以 pid (如果有指定) 或是以 init 這個(gè)基本進(jìn)程為根 (root),如果有指定使用者 id,則樹(shù)狀圖會(huì)只顯示該使用者所擁有的進(jìn)程。要是要使用這個(gè)包大家需要在所使用的linux lib和斌目錄里面增加該工具。
-A:?各進(jìn)程樹(shù)之間的連接以ASCII碼字符來(lái)連接
-U:各進(jìn)程樹(shù)之間的連接以u(píng)tf8字符來(lái)連接,某些終端可能會(huì)有錯(cuò)誤
-p:同時(shí)列出每個(gè)進(jìn)程的PID
-u:?同時(shí)列出每個(gè)進(jìn)程的所屬賬號(hào)名稱(chēng):
pstree -up 輸出進(jìn)程和子進(jìn)程樹(shù)形數(shù)據(jù)
kill <sig> <pid>和coredump文件查看線程堆棧:
因?yàn)橛行r(shí)候我們使用的linux環(huán)境下面不一定有很全的工具,例如上面所提到的pstack查看對(duì)應(yīng)的線程,會(huì)有其他的一些命令和工具替代,這里我就給大家介紹兩種我使用的方法,用來(lái)查看我實(shí)際的堆棧和對(duì)應(yīng)的pid線程信息。
kill?-11?461
對(duì)應(yīng)的進(jìn)程就會(huì) 出現(xiàn)Segmentation fault (core dumped)
而我們?cè)O(shè)置了coredump文件的產(chǎn)生,產(chǎn)生條件里面有段錯(cuò)誤信號(hào),所以我發(fā)送了11信號(hào)給該進(jìn)程。
如果大家對(duì)于自己需要的信號(hào)不知道對(duì)應(yīng)的數(shù)字,可以用 ?kill -l ?命令查詢(xún)。
至于通過(guò)coredump查看對(duì)應(yīng)的堆棧信息,我之前的這篇文章寫(xiě)的比較全面了,這里就不再過(guò)多贅述了,大家可以點(diǎn)擊這篇文章進(jìn)行查看Linux開(kāi)發(fā)coredump文件分析實(shí)戰(zhàn)分享。
除了使用kill命令殺死指定進(jìn)程,我們也可以通過(guò)top組合命令來(lái)殺死進(jìn)程:首先使用top進(jìn)入top顯示的信息,其次假如我們選擇好了 461這個(gè)進(jìn)程準(zhǔn)備殺死:
先輸入 k 進(jìn)入top的kill選項(xiàng)
PID?to?signal/kill?[default?pid?=?1451]?
??PID?USER??????PR??NI????VIRT????RES????SHR?S??%CPU??%MEM?????TIME+?COMMAND???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
??461?root?????-96?-20?2081464??28672??17756?S??21.7???1.4???0:07.05?exc??
再按照提示輸入 指定pid 461
PID?to?signal/kill?[default?pid?=?1451]?461
使用enter ?之后,按照提示輸入信號(hào),我選擇了 11( 段錯(cuò)誤信號(hào))
Send?pid??461?signal?[15/sigterm]?11
這個(gè)操作等同于 kill -11 461
gdb attach <pid>實(shí)時(shí)調(diào)試:
這個(gè)是gdb中實(shí)時(shí)調(diào)試的工具,指定進(jìn)程實(shí)時(shí)調(diào)試,但是實(shí)際中遇到大型代碼,調(diào)試起來(lái)太卡了,所以基本不用它實(shí)時(shí)調(diào)試,我是用來(lái)它來(lái)進(jìn)行實(shí)時(shí)看一些堆棧信息以及查看線程id和實(shí)際代碼的匹配。操作也是比較簡(jiǎn)單,從上面我們可以獲知你運(yùn)行的進(jìn)程的pid,你用gdb attach指定pid就可以進(jìn)行調(diào)試了。進(jìn)入之后的操作命令就是gdb調(diào)試的命令。
大家可以看到gdb attach一進(jìn)來(lái)就在最前面顯示對(duì)應(yīng)的lwp線程pid,這個(gè)pid和我們用top命令和ps命令以及strace、ltrace打印的pid信息是一致的。通過(guò)相同的pid我們就可以知道該進(jìn)程或者線程下執(zhí)行的具體操作了。
輸入gdb命令 thread apply all bt ,我們就可以看到對(duì)應(yīng)線程的堆棧,通過(guò)堆棧的信息,我們就可以反向查找代碼了。下面是一個(gè)截取,展示的是lwp 790(線程pid==790)的一個(gè)堆棧信息,通過(guò)#3 我們可以知道該線程代碼在even_manager.cpp的40行
實(shí)戰(zhàn)中的組合使用
通過(guò)上面的命令介紹,我們也知道了在linux下我們可以用到哪些工具可以分析我們的異常進(jìn)程和線程,下面我就通過(guò)一個(gè)我自己實(shí)際遇到的情況,給大家實(shí)際介紹一下這些工具的組合使用情況。
首先,我先使用top命令查看我cpu使用情況
這一看,ex進(jìn)程竟然占用了176%的cpu(我的設(shè)備是多核設(shè)備),也就是差不多兩個(gè)核的cpu被占滿(mǎn)了。此時(shí)可以看到主要占用的cpu資源是用戶(hù)態(tài)的資源,所以推薦使用ltrace查看,但是我這邊目前設(shè)備里面沒(méi)有這個(gè)包,所以直接使用了strace查看。
接下來(lái)我就想知道到底該進(jìn)程下的哪個(gè)線程,以及線程對(duì)應(yīng)的是哪部分代碼,頻繁執(zhí)行了什么操作。
所以我先使用了 top -Hp 461 查看我對(duì)應(yīng)該進(jìn)程下所有的線程執(zhí)行所占cpu的百分比。
也可以使用 ps -T -p 461 查看進(jìn)程對(duì)應(yīng)的線程pid信息
ps -eLo pid,lwp,pcpu |grep 461 查看線程執(zhí)行消耗的時(shí)間
strace -p 461 -f進(jìn)行查看該進(jìn)程下執(zhí)行了內(nèi)核交互函數(shù)最多執(zhí)行的部分
最左邊的部分就是對(duì)應(yīng)的執(zhí)行IO函數(shù)下的線程PID,我們同時(shí)可以直接指定線程pid進(jìn)行查詢(xún)線程的操作,例如我們看到線程845在讀fd為13的一個(gè)設(shè)備,我們可以單獨(dú)strace -p 845.
本來(lái)應(yīng)該是strace、ltrace、pstack配合使用,但是我使用的設(shè)備上沒(méi)有l(wèi)trace和pstack,所以我使用gdb attach直接調(diào)試進(jìn)程,查看對(duì)應(yīng)的線程堆棧信息,用來(lái)確認(rèn)top組合命令的出的線程pid信息和實(shí)際代碼進(jìn)行映射。
gdb attach 461 實(shí)時(shí)調(diào)試查看線程堆棧信息用來(lái)匹配實(shí)際的代碼部分
進(jìn)入之后直接使用 thread apply all bt ?查看對(duì)應(yīng)的線程堆棧信息,通過(guò)堆棧信息,我們就可以知道對(duì)應(yīng)的代碼部分
每一個(gè)堆棧信息的最上面有顯示 lwp <pid> 大家就可以對(duì)照查看代碼了。
這時(shí)候我們就知道了該進(jìn)程下有哪些線程,那我們還需要知道該線程對(duì)應(yīng)的是代碼哪一部分代碼,以及線程具體執(zhí)行了哪些操作。
strace和gdb attach命令等從開(kāi)發(fā)初始來(lái)說(shuō)是好的技術(shù),但是實(shí)際使用中,由于代碼復(fù)雜性,以及c受限與cpu,在我strace和gdb attach使用中,這些工具因?yàn)橐恢北O(jiān)控進(jìn)程,會(huì)很占用你cpu資源,甚至gdb attach開(kāi)始調(diào)試,機(jī)器直接運(yùn)行非常緩慢,遠(yuǎn)程ssh登錄都卡住了。所以只能用一些消耗資源少的操作進(jìn)行查看信息,就像內(nèi)存分析中的mtrace和valgrind,一啟動(dòng)使用,機(jī)器直接卡停。所以很多時(shí)候工具雖好,但是實(shí)際只能輔助一些而已,更重要我們要規(guī)范寫(xiě)代碼。
結(jié)語(yǔ)
這就是我分享我在工作中使用的一些linux線程監(jiān)控的操作,如果大家有更好的想法和需求,也歡迎大家加我好友交流分享哈。
作者:良知猶存,白天努力工作,晚上原創(chuàng)公號(hào)號(hào)主。公眾號(hào)內(nèi)容除了技術(shù)還有些人生感悟,一個(gè)認(rèn)真輸出內(nèi)容的職場(chǎng)老司機(jī),也是一個(gè)技術(shù)之外豐富生活的人,攝影、音樂(lè) and 籃球。關(guān)注我,與我一起同行。