Linux Process Exit Status
Process Termination
Linux 中 process 結束時系統會回收該 process 使用的大部分 resource,僅留下結束資訊供它的 parent 取得。parent 回收 child process、取得這些資訊後,剩餘的 resource 才會被釋放。如果 parent 沒有回收結束的 child process,child 會變殭屍(zombie),即執行結束了但沒有把 resource 釋放乾淨,會佔用 PID 及一些記憶體空間放 exit status。
parent process 透過 call wait()
回收 child process 並取得 child process 的 exit status。
process 結束分成正常結束(terminate normally)跟不正常結束(terminate abnormally or crash)。
以系統的角度來看,process call exit()
或從 main()
return 算 terminate normally。(實際上從 main()
return 後就會 call exit()
系列 function。)process crash、被 signal 結束或其他狀況算 terminate abnormally。
以程式或 programmer 的角度來看,exit()
的參數為非 0 通常代表有些檢查沒有通過,程式無法繼續完成工作才會在中間 call exit()
。這個狀況是「程式正常結束,但沒有完成該有的運作」,屬於程式執行邏輯上的錯誤,跟 crash 不同。
Process Exit Status
Linux 中以 exit status code 表示 process 結束時的狀態(它怎麼結束的)。
System
系統 exit status code 的範圍為 0 至 255。若程式設置超過 255 的 code,會以 mod 256 作為 exit code。
有些 code 已保留給系統使用、有固定意義。一般不建議 programmer 再對這些 code 定義其他意義。系統已保留的 exit code 為:0、1、2、126 ~ 165、255。
C/C++ program
在 C/C++ program 中 exit()
的參數值是在 process 正常結束下,讓 programmer 得知「程式階層上」的 exit status,跟系統所使用的 exit status code 相關但不相等。
Parent 取得 child exit status
parent process call wait()
可取得 child process 的 exit status:
1 | int status = -1; |
Parent 判斷 child 的結束狀態
parent 由 wait()
取得 的 status 值可用一些 macro 判斷意義。先以 WIFEXITED()
判斷 child 是否 terminate normally,再以其他 macro 取得更細部的資訊。
WIFEXITED()
return true對系統來說 child process 是正常結束。另假設 child process 是 call
exit(N)
結束的。WEXITSTATUS()
會 return NN == 0
以程式、programmer 觀點會認為 child process 正確完成工作。
N != 0
以程式、programmer 觀點會認為程式並未正確完成工作,可能中間檢查到問題造成程式無法完成工作(例如未設環境變數),以
exit()
的方式處理此錯誤、方便 debug。N 值的意義由 programmer 定義。
WIFEXITED()
return false對系統來說 child process 不正常結束,可用一些 macro 再做檢查:
WCOREDUMP()
:child 是否產生 core dumpWIFSIGNALED()
:child 是否因 signal 結束
其他 macro 可參考 wait()
man page。