日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
進(jìn)程無(wú)故消失的破案歷程

概述

成都創(chuàng)新互聯(lián)公司是一家專注于做網(wǎng)站、網(wǎng)站制作與策劃設(shè)計(jì),淶水網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十載,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:淶水等地區(qū)。淶水做網(wǎng)站價(jià)格咨詢:028-86922220

前段時(shí)間公司有個(gè)系統(tǒng)的進(jìn)程老是無(wú)故退出,在客戶那邊好好的,在家里服務(wù)器上老是出現(xiàn),而且出現(xiàn)的時(shí)間也沒(méi)啥規(guī)律,當(dāng)然最終查出來(lái)還是有規(guī)律的,不過(guò)這個(gè)規(guī)律比較特別。大家看了后面的內(nèi)容之后就明白了,真的很特殊!

初步分析

進(jìn)程Crash?

當(dāng)同事找到我的時(shí)候,我***反應(yīng)是是不是進(jìn)程Crash了,如果是crash,那通常情況下會(huì)有crash的日志,檢查了一遍,什么日志都沒(méi)有留下,當(dāng)然有時(shí)候Crash了,JVM也確實(shí)也不會(huì)留下Crash日志,不過(guò)這個(gè)特別罕見(jiàn)了,絕大部分是人為操作了。

被OS Kill?

既然不是Crash,那是不是系統(tǒng)存在內(nèi)存泄露,被OS Kill了,不過(guò)很快通過(guò)dmesg也排除了,因?yàn)闆](méi)有看到任何kill的跡象。

System.exit?

排除掉以上兩個(gè)因素之后,接著馬上就懷疑是否有什么代碼執(zhí)行過(guò)System.exit,于是重新編譯了一把JDK,在System的exit方法處打印了些日志,于是坐等奇跡的發(fā)生。

令人興奮的是,進(jìn)程真的消失了,可是令人遺憾的是,我們埋點(diǎn)的日志并沒(méi)有出現(xiàn)。這讓我再次陷入沉思。

回歸源碼

從日志看確實(shí)是調(diào)用了ShutdownHook

于是找到addShutdownHook源碼的位置

再次翻了一下JDK的源碼,除了正常退出,System.exit等之外還有哪些情況會(huì)調(diào)用這個(gè)Shutdown的Hook,于是將埋點(diǎn)埋到了Shutdown.runHooks方法里。

繼續(xù)等待事情再次發(fā)生,果然沒(méi)多久,當(dāng)天下午又發(fā)生了,打印了如下日志

也就是說(shuō)當(dāng)時(shí)是收到了一個(gè)SIGHUP的信號(hào),這個(gè)信號(hào)最終會(huì)讓進(jìn)程退出,JVM對(duì)這個(gè)信號(hào)確實(shí)是沒(méi)有特殊處理的,因此沒(méi)有我們看到的Crash日志。

那接下來(lái)就是要找到為什么會(huì)收到這個(gè)信號(hào)了,這個(gè)信號(hào)又是誰(shuí)發(fā)出的。

找出信號(hào)源

SIGHUP這個(gè)信號(hào),最主要發(fā)生的場(chǎng)景是Shell終端關(guān)閉一個(gè)Session的時(shí)候會(huì)對(duì)該Session關(guān)聯(lián)的進(jìn)程發(fā)送一個(gè)SIGHUP信號(hào),這個(gè)信號(hào)默認(rèn)是會(huì)退出進(jìn)程的。為此我還特地下載了ITerm2(我和同事都是mac,用的iTerm2的終端)的源碼,還真找到了幾個(gè)發(fā)送SIGHUP信號(hào)的代碼

看名字PTYTask就能猜到了,這應(yīng)該是一個(gè)seesion任務(wù),于是進(jìn)到代碼里看到主要是有兩個(gè)方法有發(fā)送SIGHUP信號(hào)給子進(jìn)程,分別是dealloc和stop,其中stop會(huì)通過(guò)sendSignal函數(shù)給子進(jìn)程發(fā)送SIGHUP信號(hào)。

對(duì)于我這種比較喜歡自虐的人,一般會(huì)想怎么就確定這個(gè)就是我要找的代碼,之前從沒(méi)有寫過(guò)Object-C的代碼,想著是否有個(gè)類似java的jmap的工具可以讓我看內(nèi)存里的對(duì)象的情況,然而臨時(shí)沒(méi)找到,不過(guò)偶然發(fā)現(xiàn)mac自帶的Activity工具就能看到一些跡象,于是在Activity里找到了iTerm2進(jìn)程,然后對(duì)其內(nèi)存數(shù)據(jù)進(jìn)行了采樣,看能否抓到類似PTYTask. dealloc或者stop的調(diào)用棧,可是比較難模擬,因?yàn)榇嬖跁r(shí)間差,點(diǎn)擊采樣的時(shí)候,很快就結(jié)束了,我還沒(méi)來(lái)得及關(guān)閉session。在看采樣報(bào)告的時(shí)候偶然看到了/usr/bin/sample的命令,原來(lái)Activity是采用這個(gè)命令進(jìn)行采樣的,于是摸索了一把,真能搞起來(lái),采樣的時(shí)間可以自定義,間隔是1ms一次,這樣可以讓我有充足的時(shí)間來(lái)操作了,于是在采樣開(kāi)啟之后,不斷地開(kāi)一個(gè)session,起一個(gè)進(jìn)程,然后close,重復(fù)做了好幾次,結(jié)束采樣之后看采樣的輸出,還真的就抓到了PTYTask.stop的調(diào)用棧

這也就驗(yàn)證了我close session的時(shí)候確實(shí)會(huì)給對(duì)應(yīng)的子進(jìn)程發(fā)送SIGHUP的信號(hào)。

那到此為止我們可以確認(rèn)的是

  • 進(jìn)程退出是因?yàn)槭盏搅诵盘?hào)SIGHUP
  • 而SIGHUP的發(fā)生是因?yàn)榻K端Session Close

那到底是不是這種情況呢?

重新復(fù)盤問(wèn)題現(xiàn)場(chǎng)

這個(gè)貌似不太可能,因?yàn)槲覀兊膕hell腳本里執(zhí)行java的時(shí)候都會(huì)帶上&,這樣進(jìn)程就會(huì)后臺(tái)運(yùn)行,不會(huì)出現(xiàn)這種session的問(wèn)題??戳讼履_本,確實(shí)是帶上了&的,自己也模擬了幾遍,在一個(gè)shell里調(diào)用帶有&的java命令,關(guān)閉終端java進(jìn)程并不會(huì)退出。難道是因?yàn)橥碌慕K端配置和我的不一樣?后來(lái)要同事發(fā)了它的iTerm2里的seesion的配置給我看了下,和我的完全一樣,這就挺奇怪了。

于是再回過(guò)來(lái)看看之前的幾次進(jìn)程消失時(shí)候的日志(我要同事有保留),看到那幾個(gè)進(jìn)程退出的時(shí)間點(diǎn),分別是

  • 2019-01-14 20:42:52
  •  2019-01-15 18:34:00
  • 2019-01-18 00:57:58
  • 2019-01-18 17:34:30

這幾個(gè)時(shí)間點(diǎn)完全沒(méi)有規(guī)律看起來(lái),不過(guò)我突然想起2019-01-18那天是周五,同事是在上海出差,而17:34:30那會(huì)應(yīng)該是快下班了,或者那會(huì)正好從上海趕車回杭州,于是問(wèn)了下那個(gè)點(diǎn)同事是不是準(zhǔn)備回杭州了,同事說(shuō)那會(huì)確實(shí)合上電腦準(zhǔn)備趕車回杭州,于是我接著問(wèn)其他幾個(gè)時(shí)間是不是差不多也是合上電腦的時(shí)間,結(jié)果還真是那么巧,既然這樣,那說(shuō)明我們的判斷方向是正確的了。

水落石出

后面突然發(fā)現(xiàn)同事修改過(guò)這個(gè)啟動(dòng)腳本,在腳本的***加了行命令

 
 
 
 
  1. java xxxx & 
  2. cd $DIR_LOG && tail -f common-*.log 

難道是這個(gè)命令搞的鬼?

突然想起一個(gè)問(wèn)題來(lái),父子進(jìn)程的問(wèn)題,假如說(shuō)當(dāng)我們?cè)趕hell里加了&跑的話,當(dāng)父進(jìn)程跑完之后,會(huì)直接將其掛到init進(jìn)程下面,也就是你通過(guò)ps -ef去看它的父進(jìn)程會(huì)是1號(hào)進(jìn)程,但是如果原來(lái)的父進(jìn)程沒(méi)有跑完,那其父進(jìn)程仍然會(huì)是原來(lái)的進(jìn)程,所以當(dāng)我們執(zhí)行這個(gè)腳本的時(shí)候,一直被執(zhí)行tail等待日志輸出,這樣一來(lái),如果我們將當(dāng)前窗口關(guān)閉了,那就意味著父進(jìn)程會(huì)退出,然后給子進(jìn)程發(fā)送SIGHUP的信號(hào),于是導(dǎo)致java進(jìn)程退出,但是如果我們?cè)趖ail日志過(guò)程中ctrl c了,那java進(jìn)程會(huì)過(guò)繼給init進(jìn)程,因此此時(shí)當(dāng)我們?cè)訇P(guān)閉窗口的時(shí)候也不會(huì)給其發(fā)送SIGHUP的信號(hào)了。

經(jīng)過(guò)驗(yàn)證果然如此,至此這個(gè)消失的進(jìn)程終于得到了解釋,嗯,好在不是我們代碼的問(wèn)題,值得欣慰,畢竟我們的代碼是要在客戶那邊運(yùn)行的,必須要保證耗穩(wěn)定性。

【本文是專欄作者李嘉鵬的原創(chuàng)文章,轉(zhuǎn)載請(qǐng)通過(guò)微信公眾號(hào)(你假笨,id:lovestblog)聯(lián)系作者本人獲取授權(quán)】

戳這里,看該作者更多好文


網(wǎng)頁(yè)名稱:進(jìn)程無(wú)故消失的破案歷程
文章起源:http://www.5511xx.com/article/dphjhsp.html