一個(gè)有趣的死循環(huán)問題

問題引出

最近在工作過程中账锹,遇到一個(gè)很有意思的bug,問題出現(xiàn)概率很小坷襟,很難復(fù)現(xiàn)奸柬,但是特別嚴(yán)重,直接導(dǎo)致用戶無法使用App婴程,屬于不可容忍的問題廓奕,因此必須解決。問題出現(xiàn)在Android-App跑壓測(cè)的過程中档叔,我們提供的第三方庫會(huì)突然停止工作桌粉,但是App的UI還是能正常的運(yùn)轉(zhuǎn),于是我以我的職業(yè)敏感性當(dāng)即做出判斷(害羞 <逃)蹲蒲,導(dǎo)致這個(gè)bug是因?yàn)槲覀兲峁┑膭?dòng)態(tài)庫中的消息線程被堵塞了番甩,從而導(dǎo)致整個(gè)庫無法工作。
通常情況下届搁,線程被堵塞住缘薛,有下面幾個(gè)原因:

  • 執(zhí)行耗時(shí)任務(wù)(如網(wǎng)絡(luò)IO或者文件IO等,導(dǎo)致整個(gè)線程卡死)
  • 死鎖(消息線程拿著A鎖卡睦,等待B鎖宴胧,數(shù)據(jù)處理線程拿著B鎖,等待A鎖表锻,相互等待恕齐,導(dǎo)致卡死)
  • 死循環(huán)(程序卡在一個(gè)循環(huán),CPU狂轉(zhuǎn)瞬逊,無法跳出)

問題定位

首先第一個(gè)思路显歧,就是在App出現(xiàn)卡主問題后,導(dǎo)出所有線程的調(diào)用堆棧确镊,查看我們自己的庫線程士骤,看哪個(gè)線程哪個(gè)函數(shù)調(diào)用存在問題,取線程堆棧蕾域,通常有兩個(gè)方法:

  • 在Android端拷肌,程序ANR后到旦,系統(tǒng)會(huì)保留該進(jìn)程的所有線程堆棧的traces文件。但是有個(gè)前提巨缘,只有主線程(UI線程)卡主的時(shí)候添忘,系統(tǒng)才會(huì)生成這個(gè)文件,其他子線程或者庫線程卡主是不會(huì)生成traces文件的若锁。
  • 出現(xiàn)問題后搁骑,讓App強(qiáng)制crash,生成crash線程堆棧拴清。我們嘗試讓UI線程強(qiáng)制crash后靶病,卻只生成了UI線程的調(diào)用棧,沒有我們庫線程的信息口予。

抓調(diào)用棧的思路否定之后娄周,我們決定先進(jìn)一步縮小問題范圍,出現(xiàn)卡主問題后沪停,我們對(duì)Android手機(jī)執(zhí)行了如下命令煤辨,找出我們App所有線程的運(yùn)行狀況。

adb shell top -m 20 -t

巧合地發(fā)現(xiàn)每次采樣數(shù)據(jù)中木张,CPU使用率最高都是我們App進(jìn)程中的同一個(gè)線程众辨,正是我們動(dòng)態(tài)庫的消息線程,而該線程的使用率竟然比圖像繪制線程占比還要高了幾倍舷礼,很明顯的異常鹃彻,因此幾乎可以斷定是該線程導(dǎo)致的卡死問題,同時(shí)也可以排除死鎖的可能性妻献,因?yàn)樗梨i會(huì)讓線程wait住蛛株,不會(huì)過多的占用CPU,同時(shí)由于我們的AppIO操作很少育拨,也就排除了文件IO和網(wǎng)絡(luò)IO谨履,基本可以確認(rèn)是死循環(huán)導(dǎo)致。

那么這個(gè)線程到底是在哪個(gè)位置卡死呢熬丧?這時(shí)候最笨的方法笋粟,效果最明顯,【二分加Log法】析蝴,加log的位置以代碼行數(shù)進(jìn)行二分切隔害捕,如果第N行日志沒有輸出,那么肯定說明問題代碼在第N-1~N行之間闷畸,于是乎最終定位到了這一段神奇的死循環(huán)代碼問題尝盼。

void TransAngleTo360(double& dAngle)
{
    while (dAngle < 0)
        dAngle += 360;
    
    while (dAngle > 360)
        dAngle -= 360;
}

這段代碼,通過兩個(gè)while循環(huán)將輸入角度歸化到0~360度之間腾啥,問題就出在這個(gè)輸入值這里东涡。通過復(fù)現(xiàn)的日志發(fā)現(xiàn),代碼走到了異常分支倘待,對(duì)某個(gè)靜態(tài)數(shù)組 double arrAngele[8]疮跑,執(zhí)行了取下標(biāo)-1的操作,arrAngele[-1]凸舵,產(chǎn)生了一個(gè)未定義的極大值祖娘,8字節(jié)的double的取值范圍是:

負(fù)值取值范圍為 -1.79769313486231570E+308 到 -4.94065645841246544E-324;
正值取值范圍為 4.94065645841246544E-324 到 1.79769313486231570E+308啊奄。

如果將1.79e+308這個(gè)數(shù)傳給TransAngleTo360函數(shù)渐苏,那么函數(shù)需要執(zhí)行5e+305次循環(huán)才能結(jié)束,假設(shè)我們的計(jì)算機(jī)每秒能執(zhí)行10億次機(jī)器指令菇夸,那執(zhí)行完這個(gè)循環(huán)的時(shí)間琼富,大約是1e+207秒。庄新。鞠眉。。

問題解決

對(duì)于函數(shù)輸入?yún)?shù)择诈,進(jìn)行超大或超小值的范圍控制械蹋,很明顯這個(gè)方法只是暫時(shí)的補(bǔ)丁,且是在你知道入?yún)⒋笮〉那疤嵯滦呱郑龅南拗苹└辏绻淮_定入?yún)⒎秶芸赡軙?huì)出問題荷科。
那么更好的做法其實(shí)是這樣的唯咬,先看整數(shù)部分有多少個(gè)360,記為cnt步做,然后用原有角度減去cnt*360即可副渴,為負(fù)數(shù)的時(shí)候?qū)?yīng)處理下就行。

void TransAngleTo360(double& dAngle)
{
    int cnt = dAngle/360;
    if (time >= 0)
        dAngle = dAngle - cnt*360;
    else
        dAngle = dAngle - (cnt - 1)*360;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末全度,一起剝皮案震驚了整個(gè)濱河市煮剧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌将鸵,老刑警劉巖勉盅,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異顶掉,居然都是意外死亡草娜,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門痒筒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宰闰,“玉大人茬贵,你說我怎么就攤上這事∫婆郏” “怎么了解藻?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)葡盗。 經(jīng)常有香客問我螟左,道長(zhǎng),這世上最難降的妖魔是什么觅够? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任胶背,我火速辦了婚禮,結(jié)果婚禮上喘先,老公的妹妹穿的比我還像新娘钳吟。我一直安慰自己,他們只是感情好窘拯,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布砸抛。 她就那樣靜靜地躺著,像睡著了一般树枫。 火紅的嫁衣襯著肌膚如雪直焙。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天砂轻,我揣著相機(jī)與錄音奔誓,去河邊找鬼。 笑死搔涝,一個(gè)胖子當(dāng)著我的面吹牛厨喂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播庄呈,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼蜕煌,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了诬留?” 一聲冷哼從身側(cè)響起斜纪,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎文兑,沒想到半個(gè)月后盒刚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡绿贞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年因块,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片籍铁。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡涡上,死狀恐怖趾断,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吩愧,我是刑警寧澤歼冰,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站耻警,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏甸怕。R本人自食惡果不足惜甘穿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望梢杭。 院中可真熱鬧温兼,春花似錦、人聲如沸武契。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽咒唆。三九已至届垫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間全释,已是汗流浹背装处。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留浸船,地道東北人妄迁。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像李命,于是被迫代替她去往敵國(guó)和親登淘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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

  • ORA-00001: 違反唯一約束條件 (.) 錯(cuò)誤說明:當(dāng)在唯一索引所對(duì)應(yīng)的列上鍵入重復(fù)值時(shí)封字,會(huì)觸發(fā)此異常黔州。 O...
    我想起個(gè)好名字閱讀 5,176評(píng)論 0 9
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,089評(píng)論 1 32
  • 本文出自 Eddy Wiki ,轉(zhuǎn)載請(qǐng)注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 2,055評(píng)論 0 14
  • 國(guó)貿(mào)162單凌云40 又是一年冬季即將到來阔籽,在這個(gè)時(shí)候我們最需要的是什么?也許...
    Amao666閱讀 931評(píng)論 0 0
  • “喂仿耽,老公合冀,出來了沒,我已經(jīng)到了项贺。哦哦君躺,好的峭判,路上小心,待會(huì)見” 小凡掛下電話棕叫,先點(diǎn)了一杯蜜橘茶林螃,滿口滿心甜蜜蜜。...
    zoe_1b5f閱讀 1,041評(píng)論 0 0