引言
上星期新加一好友,在好友的朋友圈動(dòng)態(tài)里看到一張聊天截圖,是署名為“閱碼場(chǎng)”的Linux內(nèi)核技術(shù)交流群, 群友提問(wèn):
“請(qǐng)教一個(gè)Bash的問(wèn)題:有沒(méi)有什么辦法讓一個(gè)新開(kāi)的進(jìn)程,一開(kāi)始就處于暫停狀態(tài),直到我輸入fg?”
巧了,上星期我在嘗試使用ftrace根據(jù)進(jìn)程號(hào)(PID)過(guò)濾、跟蹤內(nèi)核執(zhí)行過(guò)程時(shí),迫切需要一個(gè) 進(jìn)程啟動(dòng)后處于暫停狀態(tài) ,與這位群友一樣,也是滿世界尋找Bash是否有內(nèi)置類似該功能,為什么我需要它呢?
倘若一個(gè)應(yīng)用程序是死循環(huán),或者執(zhí)行時(shí)間相對(duì)較舊,哪怕只執(zhí)行1秒,我Left Golden Finger完全可以輸入 “Ctrl+Z” 暫停它,借助pidof獲取進(jìn)程的PID號(hào),將其填入set_ftrace_pid僅過(guò)濾該進(jìn)程信息,輸入 “fg” 恢復(fù)進(jìn)程執(zhí)行。
再看另一個(gè)應(yīng)用場(chǎng)景,若某個(gè)進(jìn)程執(zhí)行耗時(shí)很短呢?例如“echo”命令轉(zhuǎn)瞬即逝,完全沒(méi)有反應(yīng)的機(jī)會(huì)。
再舉例,倘若我就想抓取從應(yīng)用程序開(kāi)始執(zhí)行到“Ctrl+Z”之間幾百毫秒的內(nèi)核執(zhí)行過(guò)程,我又該怎么?
“拿到源碼重新編譯,在main函數(shù)開(kāi)始時(shí)添加足夠的延時(shí)。”頭上長(zhǎng)尖角的小人說(shuō)。
“耍流氓!無(wú)恥!偷換概念!”頭上另一個(gè)長(zhǎng)翅膀小人指責(zé)。
好吧,別辯論了,回歸正題。
既然群友都和我一樣沒(méi)能找到Bash內(nèi)置實(shí)現(xiàn),再怎么說(shuō)“閱碼場(chǎng)”聊天群也是人類高質(zhì)量碼農(nóng)的聚集地,我相信他也不是伸手黨。那么是時(shí)候造車子了,寫幾行代碼實(shí)現(xiàn)這個(gè)功能,沒(méi)騙你,真幾行,發(fā)個(gè)信號(hào)而已。
怎么做
先貼代碼再解釋。
首先要了解系統(tǒng)快捷鍵Ctrl+Z以及命令fg本質(zhì)是做了什么,Ctrl+Z是向前端應(yīng)用發(fā)送 SIGSTOP信號(hào) ,fg恢復(fù)最近一個(gè)被暫停的應(yīng)用發(fā)送 SIGCONT信號(hào) ,并放到前臺(tái)來(lái)執(zhí)行。
SIGSTOP對(duì)應(yīng)信號(hào)19、SIGCONT對(duì)應(yīng)信號(hào)18,正如代碼23行和31行所做的那樣。你不相信,那就用API signal()去截獲這兩個(gè)信號(hào)的處理函數(shù)。
既然是信號(hào)觸發(fā),那就能用kill命令去替代Ctrl+Z和fg動(dòng)作:
kill -19
kill -18
命令輸入 “kill -l” 可查閱到所有信號(hào)。
寫個(gè)測(cè)試程序
寫另外一個(gè)測(cè)試程序child.c,僅打印進(jìn)程的PID號(hào),以及調(diào)試主進(jìn)程是否能成功傳遞參數(shù)給子進(jìn)程。
文稿貼的兩張圖是測(cè)試的方法,主進(jìn)程傳遞給子進(jìn)程3個(gè)參數(shù)“aa bb cc”,剛啟動(dòng)后子進(jìn)程被信號(hào)暫停(T),左側(cè)輸入回車后子進(jìn)程得以運(yùn)行(S)。
使用新輪子
恩,輪子造好了,看看它的效果怎么樣,用它協(xié)助ftrace抓取echo的執(zhí)行。
思考
現(xiàn)在左邊窗口輸入./master.elf echo abcdefg,切換到右側(cè)窗口輸入腳本ftrace-pid.sh,這個(gè)腳本將抓取1秒的數(shù)據(jù),再切換到左側(cè)窗口按Enter鍵。打開(kāi)trace文件/tmp/a.txt,怎么樣了,echo命令的執(zhí)行信息被抓取下來(lái)了。
實(shí)驗(yàn)里用到的ftrace-pid.sh腳本我把他的源碼貼在下面。
思考
我在使用kill發(fā)送信號(hào)時(shí)有個(gè)疑問(wèn),既然應(yīng)用程序收到SIGSTOP信號(hào)后就處于停止?fàn)顟B(tài),既然停止了,為什么還能處理之后的SIGCONT信號(hào)呢?之前是進(jìn)程可運(yùn)行,才能被調(diào)度、能處理信號(hào),很好理解。之后進(jìn)程都停止了,又怎么能處理SIGCONT信號(hào)恢復(fù)執(zhí)行呢?你能夠用鼠標(biāo)點(diǎn)擊左下角“開(kāi)始”菜單關(guān)閉計(jì)算機(jī),卻無(wú)法繼續(xù)用鼠標(biāo)使其開(kāi)機(jī)。所以我猜測(cè)信號(hào)處理首先是由于調(diào)度器處理的。
第二個(gè)擴(kuò)展問(wèn)題,gdb調(diào)試應(yīng)用程序是可以暫停應(yīng)用程序執(zhí)行的,它使用的是ptrace。你能否寫一個(gè)應(yīng)用程序,它利用ptrace原理去暫停子進(jìn)程執(zhí)行。我說(shuō)的暫停位置可不是main,甚至在main之前。應(yīng)用程序啟動(dòng)時(shí) “第一個(gè)系統(tǒng)調(diào)用是什么?” 嘗試找到它,并截獲。
原文標(biāo)題:僅40行代碼,Linux如何以暫停狀態(tài)啟動(dòng)新進(jìn)程,當(dāng)然是發(fā)送信號(hào)呀
文章出處:【微信公眾號(hào):一口Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
審核編輯:湯梓紅
-
Linux
+關(guān)注
關(guān)注
87文章
11207瀏覽量
208721 -
代碼
+關(guān)注
關(guān)注
30文章
4722瀏覽量
68234 -
應(yīng)用程序
+關(guān)注
關(guān)注
37文章
3237瀏覽量
57547
原文標(biāo)題:僅40行代碼,Linux如何以暫停狀態(tài)啟動(dòng)新進(jìn)程,當(dāng)然是發(fā)送信號(hào)呀
文章出處:【微信號(hào):yikoulinux,微信公眾號(hào):一口Linux】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論