BUG FIX:程序退出時hang住
問題描述
程序kill後遲遲不退出,pstack看到一直在等鎖:
Thread 1 (Thread 0x2b3db1e9d900 (LWP 83917)): #0 0x00002b3db6193f4d in __lll_lock_wait () from /lib64/libpthread.so.0 #1 0x00002b3db61915ae in _L_lock_39 () from /lib64/libpthread.so.0 #2 0x00002b3db61914e8 in [email protected]@GLIBC_2.3.2 () from /lib64/libpthread.so.0 #3 0x00002b3dbd7a9736 in CSequenceRuntime::~CSequenceRuntime (this=0x2b3dbd9af340 <CSequenceRuntime::m_cInstance>, __in_chrg=<optimized out>) at mf_util.cpp:95 #4 0x00002b3db7aaae69 in __run_exit_handlers () from /lib64/libc.so.6 #5 0x00002b3db7aaaeb5 in exit () from /lib64/libc.so.6 #6 0x00002b3db7a93b1c in __libc_start_main () from /lib64/libc.so.6 #7 0x00000000004022b9 in _start ()
檢查
很明顯,在執行exit時呼叫__run_exit_handlers
執行全域性變數/靜態變數的解構函式。全域性變數的解構函式中destroy一個條件變數。條件變數釋放時一直在等鎖,按理來說沒有其他執行緒拿到條件變數的鎖,而且條件變數的幾個介面pthread_cond_signal
,pthread_cond_wait
, pthread_cond_broast
等都不會長時間拿著條件變數內部的鎖。
用gdb檢視一下pthread_cond_t
的資訊(這裡只貼出來了條件變數的資料):
m_signalCond = {__data = {__lock = 2, __futex = 2, __total_seq = 18446744073709551615, __wakeup_seq = 1, __woken_seq = 1, __mutex = 0x2b65fb6eb360 <CSequenceRuntime::m_cInstance+32>, __nwaiters = 0, __broadcast_seq = 1}, __size = "\002\000\000\000\002\000\000\000\377\377\377\377\377\377\377\377\001\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000`\263n\373e+\000\000\000\000\000\000\001\000\000", __align = 8589934594},
注意看,條件變數的__total_seq
的值非常大,是uint64_t(-1)。BUG主機環境上的glibc版本是2.17,通過程式碼檢視只有在執行過pthread_cond_destroy
之後才會設定為-1。這樣就有一個猜想,是不是這個條件變數已經釋放過一次,或者包含這個條件變數的物件已經釋放過一次,再進一步,就是全域性變數兩次釋放,或者有多次釋放的問題。
因為這個場景很容易重現,就用gdb跟蹤了一下,確實存在兩次釋放,而且在第二次釋放的時候會hang在這裡。
全域性變數正常情況下只會釋放一次,只有在不同的連結庫中存在相同名字的全域性物件時,才會釋放兩次。
用一個指令碼把所有的連結庫都檢查一遍,看是否有兩個連結庫包含這個全域性變數即可。pstack資訊中展示呼叫pthread_cond_destroy
CSequenceRuntime::m_cInstance
,用個指令碼檢查一下:
for file in `ls *.so`
do
res=`nm $file | grep _ZN16CSequenceRuntime11m_cInstanceE`
if [ "${res}x" != "x" ]
then
echo `ls -l $file` $res
fi
done
_ZN16CSequenceRuntime11m_cInstanceE
這個名字是我知道在哪個連結庫中包含這個符號,先用nm查出來的:
lnbillkj%nm libxxxxD.so | grep CSequenceRuntime | grep m_cInstance
000000000020f300 B _ZN16CSequenceRuntime11m_cInstanceE
通過上面的指令碼遍歷檢查,發現有個連結庫本來應該是軟連結,結果變成了真實檔案。應該是操作人員把ln命令寫成了cp。
輸出結果:
-rwxr-xr-x 1 bill aigrp 472728 Sep 26 09:26 libmdb_frame_baseD.so 000000000020f340 B _ZN16CSequenceRuntime11m_cInstanceE
-rwxr-xr-x 1 bill aigrp 3789018 Sep 26 09:26 libmdb_in_baseD.so U _ZN16CSequenceRuntime11m_cInstanceE
-rwxr-xr-x 1 bill aigrp 3789018 Sep 26 09:25 libMdbInD.so U _ZN16CSequenceRuntime11m_cInstanceE
-rwxr-xr-x 1 bill aigrp 472728 Sep 26 09:24 libMFBaseD.so 000000000020f340 B _ZN16CSequenceRuntime11m_cInstanceE
連結庫名字後面的字母U
表示符號未定義,只是在連結庫中引用了,B
表示符號在未初始化的資料區中(BSS)。更多資訊請看考man nm
。
網上也看到兩個文章介紹全域性變數多次析構的問題,不過與本例稍有不同,可以參考漲姿勢:
- 技巧:多共享動態庫中同名物件重複析構問題的解決方法
這兩篇文章對全域性變數多次析構的原理進行了闡述,閱讀非常有益。第1篇文章中介紹說如果同一個實現檔案(cpp檔案)被多個連結庫編譯進去,而程式同時引用這兩個連結庫,就會出現兩個重名的全域性變數。第2篇介紹在標頭檔案中定義了全域性變數(其實大型程式中絕對不會允許這麼做),多個連結庫引用了這個標頭檔案,而可執行程式同時引用了這些連結庫,就會出現多個同名連結庫。
另外,除了上面兩篇文章介紹的造成一個全域性符號在兩個連結庫中定義,最近還發現一個情況,就是extern Class::static_member
。
比如:
/// test.h
class A
{
public:
int a;
static A sa;
};
cpp實現:
test.cpp
#include "test.h"
extern A A::sa; // 按照常規理解 extern只是變數宣告,不帶實現,然而事實並非如此
編譯:
g++ test.cpp -o libtest.so -shared -fPIC -std=c++11
檢查符號:
nm libtest.so | grep sa
輸出結果:
[~]$ nm libtest.so | grep sa
0000000000201054 B _ZN1A2saE # B表示該符號已經定義
c++filt _ZN1A2saE
是 A::sa
。
呆若木雞。
相關推薦
BUG FIX:程序退出時hang住
問題描述 程序kill後遲遲不退出,pstack看到一直在等鎖: Thread 1 (Thread 0x2b3db1e9d900 (LWP 83917)): #0 0x00002b3db6193f4d in __lll_lock_wait () from /l
linux c開發: 在程序退出時進行處理
ack 自己 main class ctr ace its func 語言 有時候,希望程序退出時能進行一些處理,比如保存狀態,釋放一些資源。c語言開發的linux程序,有可能正常退出(exit),有可能異常crash,而異常crash可能是響應了某信號的默認處理。這裏總結
linux系統程式設計之程序(四):程序退出exit,_exit區別即atexit函式
一,程序終止有5種方式: 正常退出: 從main函式返回 呼叫exit 呼叫_exit 異常退出: 呼叫abort 由訊號終止 二,exit和_exit區別: 關於_exit(): #include <unistd.h>
IDEA驚天bug:程序已結束,退出程式碼-1073741819 (0xC0000005)
由於昨天要寫的文章沒有寫完,於是今天早上我四點半就“自然醒”了,心裡面有事,睡覺也不安穩。洗漱完畢後,我開啟電腦,正襟危坐,擺出一副要幹架的態勢,不能再拖了。 要寫的文章中涉及到一串程式碼,關於 Undertow 的一個入門示例,貼出來大家看一下。 public class Underto
Android項目實戰(二):安卓應用程序退出的三種方法
eat 延遲 用戶 pre html port length tst 二次 原文:Android項目實戰(二):安卓應用程序退出的三種方法現在的APP退出的時候都不是讓用戶點擊了“後退鍵”就退出。防止用戶點錯了後退鍵而造成的用戶體檢不好。 一年前搞
Spring-boot構建多模塊依賴工程時,maven打包異常:程序包xxx不存在
core 核心 === 指定 apach 模塊 spring plugin fig 在qizhi項目改版的時候, 所有代碼都遷移好了, 但是compile的時候報程序包*****不存在, 具體到某一個類就是: 找不到符號. 下面這篇文章是正解 http://hbxflihu
python 64式: 第17式、死鎖或程序hang住除錯方法
步驟1:下載python-debuginfo 如果已經發現有/etc/yum.repos.d/xxx-Debuginfo.repo,就不需要下載 修改 /etc/yum.repos.d/xxx-Debuginfo.repo 將其中的 enabled=0 修改為 enabled=1 步驟2:下載gd
Jenkins——應用篇——如何解決execute shell中啟動的程序被在Job退出時被殺死問題
在部落內部時不時的會有同學問一為什麼在execute shell中不能啟動tomcat、為什麼在windows batch中不能啟動tomcat等問題,其實大部分情況下不是不能啟動,而是啟動後隨著job結束程序被殺死,造成不能啟動的假象,這一點從tomcat的日誌中可以看來,
編譯qt工程時出現qt外掛程序退出錯誤的解決辦法
真名:朱金燦 主要經歷:本科畢業於CUG(武漢)的GIS專業,畢業後參加工作,現在在北京從事軟體開發和團隊管理工作。曾獲有色金屬工業科技進步獎二等獎(獲獎證書連結)。 我的聯絡方式: EMAIL:clever101#163.com 研究方向: 數字影象處理、計算機圖形學。 本部落格內
父程序異常退出時, 殺死所以子程序
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <stdli
linux終端關閉時為什麼會導致在其上啟動的程序退出?
現象 經常在linux下開發的人應該都有這樣的經驗,就是在終端上啟動的程式,在關閉終端時,這個程式的程序也被一起關閉了。看下面這個程式,為了使程序永遠執行,在輸出helloworld後,迴圈呼叫sleep: 直接關閉這個終端,在另一個終端上查詢該程序,已
linux程序退出的時exit,_exit區別和聯絡
一,程序終止有5種方式: 正常退出: 從main函式返回呼叫exit呼叫_exit 異常退出: 呼叫abort由訊號終止 二,exit和_exit區別: 關於_exit(): #include <unistd.h> void _exit(int stat
程序跟蹤時Session老丟失,日誌:拒絕了對物件 'sp_sdidebug'(資料庫 'master',所有者 'dbo')的 EXECUTE 許可權
非常奇怪的錯誤: 如果一開始就用程序跟蹤, 根本無法登入。 如果登入進去之後再程序跟蹤, 很容易發生 Session 丟失。 日誌裡顯示:“拒絕了對物件 'sp_sdidebug'(資料庫 'master',所有者 'dbo')的 EXECUTE 許可權”。 處理方
Mysql基準測試詳細解說(根據慕課網:《打造扛得住Mysql數據庫架構》視頻課程實時筆錄)
status imu 連接線 慕課 正在 option 並且 nod ces 什麽是基準測試 基準測試是一種測量和評估軟件性能指標的活動用於建立某個時刻的性能基準,以便當系統發生軟硬件變化時重新進行基準測試以及評估變化對性能的影響。 我們可以這樣認為:基準測試是針對
Jira強制退出時(如意外停電)再啟動報Locked錯誤的幾個解決辦法
mode ogr pro 推薦 dev 重啟 如意 文件的 mod 方案1.先刪掉 jira_home下的.jira-home.lock,再重啟 jira_home指你的Jira安裝目錄,如D:/Program Files/Atlassian/Application
C++雜記:運行時類型識別(RTTI)與動態類型轉換原理
程序包 bar ons Language 值類型 包括 iat www != 運行時類型識別(RTTI)的引入有三個作用: 配合typeid操作符的實現; 實現異常處理中catch的匹配過程; 實現動態類型轉換dynamic_cast。 1. typeid操
數據庫性能優化三:程序操作優化
變量 全局 new href 客戶端程序 color 聚合 ont delete 數據庫優化包含以下三部分,數據庫自身的優化,數據庫表優化,程序操作優化.此文為第三部分 數據庫性能優化三:程序操作優化 概述:程序訪問優化也可以認為是訪問SQL語句的優化,一個好的
【翻譯自mos文章】當點擊完 finishbutton後,dbca 或者dbua hang住
cat queue class pop trace rom base done automatic 當點擊完 finishbutton後,dbca 或者dbua hang住 來源於: DBCA/DBUA APPEARS TO HANG AFTER CLICKIN
python 獲取程序退出狀態碼
pythonimport systry: sys.exit(1)except SystemExit,e: print e1python 獲取程序退出狀態碼
學習小記:JS判斷時特殊值與boolean類型的轉換
ring something mbo true mage js框架 temp some .info 扒開JQuery以及其他一些JS框架源碼,常常能看到下面這樣的判斷, 寫慣了C#高級語言語法的我,一直以來沒能系統的理解透這段代碼。 var test; //do