自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一次Linux中定位c++程序運(yùn)行異常的經(jīng)歷

系統(tǒng) Linux
今天下午我遇到了一些棘手的問題,因?yàn)樵趍ips64上編譯程序,經(jīng)常出現(xiàn)程序編譯不出來,或者運(yùn)行不正常,花了很長的時(shí)間定位,最后和同事一些解決了,下面分享出來我提煉出來的一些核心定位問題的步驟。

今天下午我遇到了一些棘手的問題,因?yàn)樵趍ips64上編譯程序,經(jīng)常出現(xiàn)程序編譯不出來,或者運(yùn)行不正常,花了很長的時(shí)間定位,最后和同事一些解決了,下面分享出來我提煉出來的一些核心定位問題的步驟。

子線程創(chuàng)建不出來

猜測:go的程序都能創(chuàng)建出子線程,但是c++的創(chuàng)建不出來,但是在 x86 可以,是不是什么 linux 系統(tǒng)限制?

正常表現(xiàn)

異常表現(xiàn)

解決方法:加錯(cuò)誤日志進(jìn)行調(diào)試(最 lower 辦法)

找到報(bào)錯(cuò)點(diǎn):

錯(cuò)誤日志內(nèi)容

查詢 man 手冊,看看是不是能找到有幫助的東西:

  1. man pthread_attr_setstacksize 

打印出解釋:

  1. ERRORS 
  2.        pthread_attr_setstacksize() can fail with the following error: 
  3.  
  4.        EINVAL The stack size is less than PTHREAD_STACK_MIN (16384) bytes. 
  5.  
  6.        On some systems, pthread_attr_setstacksize() can fail with the error EINVAL if stacksize is not a multiple of the system page size. 

翻譯上面的話,可能會產(chǎn)生這個(gè)錯(cuò)誤:

  • EINVAL 堆棧大小小于 PTHREAD_STACK_MIN(16384) 字節(jié)。
  • 在某些系統(tǒng)上,如果 stacksize 不是系統(tǒng)頁面大小的倍數(shù), pthread_attr_setstacksize() 可能會失敗,并顯示錯(cuò)誤 EINVAL

查詢 linux 報(bào)錯(cuò)碼含義, 得知錯(cuò)誤碼 22 果然和 man 手冊中說的一致,是參數(shù)有問題。

錯(cuò)誤碼對照

第一次嘗試:擴(kuò)大線程棧到上面說的 16384 ,但還是報(bào)錯(cuò)

錯(cuò)誤日志內(nèi)容

根據(jù)經(jīng)驗(yàn),查看最小頁大小,發(fā)現(xiàn)是 16k , 而 x86 架構(gòu)是 4K ,原來用的 20K 是不對齊的,怪不得創(chuàng)建不出來線程。

查看系統(tǒng)頁大小

依次嘗試, 最終發(fā)現(xiàn) 10*16K 子線程成功創(chuàng)建。

但是不準(zhǔn)確,按其說法,應(yīng)該是設(shè)置 PAGESIZE 的整數(shù)倍都行,懷疑其對最小值有要求。c++ 的頭文件在 /usr/include 目錄下面, PTHREAD_STACK_MIN 是一個(gè)常量,估計(jì)里面會有定義,嘗試查找

  1. $ grep -rl PTHREAD_STACK_MIN * 
  2. bits/local_lim.h 
  3. pthread.h 

還真讓我找到了, 根據(jù)英文注釋,至少要兩個(gè) 64K 作為線程棧,才能跑起一個(gè)線程。

系統(tǒng)c++頭文件中的提示信息

至此問題解決。

部分線程卡住

我發(fā)現(xiàn)程序雖然正常運(yùn)行,但是部分功能不正常,經(jīng)過查看日志發(fā)現(xiàn),有一個(gè)線程只執(zhí)行了一半就卡住了。

經(jīng)過查看日志可以定位出是哪個(gè)線程卡住,如果從日志看不出來也沒關(guān)系??梢允褂?pstack 進(jìn)程號 看一些進(jìn)程堆棧。

查看進(jìn)程 pid:

  1. ps -ef |grep 進(jìn)程名 

使用 gdb 查看是否出現(xiàn)問題,兩個(gè)重要命令:

  1. gdb attach {pid} #查看正在運(yùn)行程序的棧 
  2. info thread #進(jìn)入以后使用,查看線程信息 

找到錯(cuò)誤位置,出現(xiàn)了 fgets() 和 read() 函數(shù),懷疑是此處出現(xiàn)問題。

gdb attach命令結(jié)果

錯(cuò)誤代碼位置

懷疑 1:_LINE_LENGTH 1024 長度太短,接受命令返回值后超過了數(shù)組本身的長度,覆蓋了未知的內(nèi)存。

這種情況我以前遇到過,表現(xiàn)應(yīng)該是程序直接就崩潰了。

懷疑 2:執(zhí)行命令的時(shí)候卡了,導(dǎo)致后面的程序沒有執(zhí)行。

根據(jù) gdb 打印出來的參數(shù),執(zhí)行 linux 命令進(jìn)行測試,果然是卡在這了!

再次使用 pstree -p {pid} 查看,確實(shí)主線程,調(diào)用了 linux 命令卡住。

查看此進(jìn)程的線程樹

接下來解決卡命令的問題。

解決 1:加 timeout 處理空返回。下面是示例命令,并不是我使用的命令。

  1. timeout 5 ls -al 

代表超過 5 秒返回。

解決 2:定位為什么這個(gè) linux 命令會卡住。

  1. strace ls -al 

直到解決為止。這就是今晚我加班到 10 點(diǎn) 30 解決的問題,我又用了一個(gè)小時(shí)總結(jié)下整個(gè)過程備忘,希望對你也有幫助。

 

責(zé)任編輯:趙寧寧 來源: 編程三分鐘
相關(guān)推薦

2012-08-28 09:21:59

Ajax查錯(cuò)經(jīng)歷Web

2011-08-19 15:05:29

異常處理

2021-12-06 19:29:17

LRU內(nèi)存算法

2023-03-29 09:36:32

2025-03-17 10:01:07

2013-01-17 10:31:13

JavaScriptWeb開發(fā)firebug

2021-04-13 18:17:48

Hbase集群配置

2013-04-01 10:27:37

程序員失業(yè)

2011-04-13 09:21:30

死鎖SQL Server

2016-12-06 09:34:33

線程框架經(jīng)歷

2020-11-02 09:48:35

C++泄漏代碼

2021-01-22 05:35:19

Lvm模塊Multipath

2011-06-16 08:58:57

軟考程序員

2012-07-12 14:35:31

面試經(jīng)歷

2015-04-28 15:31:09

2022-06-10 11:06:23

服務(wù)下線

2018-09-14 10:48:45

Java內(nèi)存泄漏

2014-07-17 13:14:11

Linux服務(wù)器網(wǎng)卡

2017-11-09 09:06:29

流量暴增優(yōu)化

2020-11-23 07:13:13

Nodejs源碼
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號