Linux下異常訊號

來源:互聯網
上載者:User

我們介紹一些標準訊號的名稱以及它們代表的事件。每一個訊號名稱是一個代表正整數的宏,但是你不要試圖去推測宏代表的具體數值,而是直接使用名稱。這是因為這個數值會隨不同的系統或同樣系統的不同版本而不同,但是名稱還算是標準化和統一的。
   這些名稱定義在signal.h中。
   int NSIG是一個定義的宏,它描述了定義的訊號的數量。由於訊號的數值是從0開始連續分配的,所以,NSIG比系統中所定義的最大的訊號數值大1。

11.2.1 程式出錯訊號
   下面介紹的訊號是有程式的錯誤造成的。這些嚴重的錯誤會被電腦或作業系統檢測出來。一般情況下,產生了這種訊號表明你的程式遭到嚴重的破壞,沒有辦法繼續完成產生錯誤的計算。
   很多程式要控制這些訊號是要在程式退出前進行一些清理工作。比如,關閉臨時檔案,清理緩衝區等。程式可以註冊一個函數控制代碼來完成這些工作,然後在讓系統執 行預設的操作來結束進程的執行。終止可能是產生這類錯誤的程式的最後的操作,但也有例外,比如一些在解釋環境中執行的程式,產生錯誤時需要返回解釋環境本 身。
   這類訊號的預設動作就是終止程式的執行。如果你定義了自己的處理,而沒有最後調用終止進程,或者阻塞或忽略了該訊號,那麼你的程式可能會造成極其嚴重的後果。除非這個訊號本身並不是出錯產生的,而是通過調用kill函數或raise函數直接通過系統發送的。
   當這些訊號結束進程時,系統會產生一個核心轉儲檔案,用來記錄發生錯誤退出前程式的狀態。核心轉儲檔案的檔案名稱是core,它會被寫到當前進程的目前的目錄 中。在Linux系統中,你也可以通過環境變數COREFILE來設定產生核心轉儲檔案的檔案名稱。產生核心轉儲檔案的目的是協助你事後利用調試器查明產生 錯誤的原因。
   下面逐一介紹這類訊號的名稱:
   int SIGFPE
   這個訊號表明產生了一個致命的算術運算錯誤。儘管該訊號的名稱來源於“浮點異常(floating-point exception)”,但是,它實際上包含了所有的算術指令錯誤,包括除數是0和溢出等。
   int SIGILL
   這個訊號的名稱來源於“非法的指令(illegal instrution)”,它往往意味著你的程式要執行根本無法解碼的指令或你無權執行的特權指令。既然C語言只能編譯產生有效合法的指令,所以 SIGILL訊號很多情況下表明可執行檔破壞了,或者正在把資料當作代碼來執行。後一種情況往往是由於把一個指標錯當成函數指標傳遞,或者數組越界破壞 了堆棧段的資料,使其中的函數返回地址錯誤等。SIGILL也可以由堆疊溢位,或者系統無法執行傳遞給系統的訊號響應函數的控制代碼引起。
   int SIGSEGV
   當程式試圖讀或寫系統分配給它的記憶體以外的儲存空間,或者寫只有讀許可權的儲存空間時會發生這個訊號。實際上,由於作業系統檢測機制的限制,對程式的檢測並不是 那麼及時,往往只有當超出範圍很遠時系統才會檢測出來。訊號的名稱來源於“段變異(segmentation violation)”。這個訊號的發生往往是由於引用沒有初始化或空的指標,或者用指標引用數組時由於疏於檢查而越界。
   int SIGBUS
   這個訊號由於引用無效的指標產生。和SIGSEGV相似,典型情況下,它也是由於沒有正確初始化指標引起的。它們的區別是,SIGSEGV是用無效的指標 引用了有效記憶體位址,而SIGBUS是引用了無效的記憶體位址。SIGBUS通常的產生是因為沒有正確初始化指標變數,比如,指標指向8位元組對齊的變數而 引用的地址是奇數。該訊號的名稱是“匯流排錯誤(bus error)”的縮寫。
   int SIGABRT
   這個訊號是程式調用函數abort()產生的。關於函數abort()的用法,參見前面的有關章節。
   int SIGIOT
   在Linux系統中,它是SIGABRT的另一個名稱。
   int SIGTRAP
   該訊號是由電腦的斷點指令產生的。偵錯工具使用該訊號。當程式執行到設定斷點的指令,引起發送該訊號,同時偵錯工具捕獲該訊號,獲得控制權,進行程式的調試。因此,你的程式是無法看到該訊號的。
   int SIGEMT
   類比自陷訊號。它是由系統未能實現,必須由軟體類比的指令引起的。截獲該訊號,並在軟體中類比引起訊號的指令的執行。
   int SIGSYS
   錯誤的系統調用。就是說,程式進行了系統調用,但是傳遞給系統的調用號是錯誤的,系統無法完成調用。

11.2.2 程式終止訊號
   這些訊號都是用來告訴程式通過某種方式結束。它們之所以有各種不同的名稱,是因為它們使用的目的稍有不同,或者程式希望用稍微不同的方式處理它們。雖然這 些訊號對程式的後果都是相同的,都是結束程式的執行,但還是有理由處理這些訊號。通常是因為程式希望在結束之前能夠清理一下,比如,能夠紀錄下某中狀態, 等等。
   預設的處理(目前)是結束進程的執行。
   int SIGTERM
   該訊號是一個最普通的讓程式結束的訊號。進程可以阻塞、控制和忽略該訊號,它是禮貌的要求一個程式結束的普通的方法,比如,通過shell命令kill在預設情況下就發送該訊號結束進程。
   int SIGINT
   該名稱是program interrupt的縮寫,當使用者從控制台輸入終止字元(通常是Ctrl-c)時發送給進程的訊號。
   int SIGQUIT
   該訊號和SIGINT相似,區別是它通過使用者輸入退出字元(通常是Ctrl-/)來產生,進程處理退出外,還要產生核心轉儲,就象接收到了錯誤訊號一樣。 對於這個訊號,你可以認為是使用者發現了程式錯誤而通知程式的一種方法。在處理該訊號時,某些退出清理最好不要做,這樣能夠讓使用者可以通過轉儲的核心來察看 當時的狀態。
   int SIGKILL
   SIGKILL訊號用來讓進程立即終止,它不能被控制和忽略,總是致命的,也不能阻塞。該訊號通常只能通過特定的命令直接產生,既然它是不可忽略的,你應 該把它作為最後的手段使用,而首先使用不太激烈的手段,如Ctrl-c或者SIGTERM等方法。如果一個進程對其它結束訊號沒有響應,則採用 SIGKILL訊號,總是能讓程式結束。事實上,如果SIGKILL訊號也不起作用的話,你就應該報告一個核心錯誤。當一個進程由於某中原因不能在進行下 去的時候,系統也能夠發送該訊息結束進程的執行。
   int SIGHUP
   SIGHUP訊號(hang up)報告使用者的終端已經從系統中斷開,或者用來作為作業控制的手段。

11.2.3 鬧鐘訊號
   這類訊號用來表明定時器啟用,訊號的預設行為是讓進程結束。雖然這種預設行為通常是沒有什麼用處的,但是沒有其它的預設行為可用。因此,往往需要程式用自己的函數控制該類訊號的行為。
   int SIGALRM
   該訊號被使用實際時間或時鐘數的定時器使用,比如,alarm()函數。
   int SIGVTALRM
   該函數被使用當前進程使用的CPU時間的函數使用。
   int SIGPROF
   該訊號用來表明當前進程使用的CPU時間和為當前進程服務的系統消耗的CPU時間的綜合,一般用來產生代碼的簡略概括。

11.2.4 非同步I/O訊號
   這類訊號和非同步I/O操作有關,你必須通過直接調用fcntl()函數才能使某些檔案描述符產生該訊號。該訊號的預設動作是忽略該訊號的作用。
   int SIGIO
   SIGIO訊號是當某個開啟的檔案描述符已經準備好輸入輸出時才會發送該訊號。在許多系統上,只有終端和套介面才可能發送這個訊號,而普通的檔案不會發送這個訊號。在GNU系統上,任何檔案,只要你說明它是非同步開啟,就可能發送這個訊號。
   int SIGURG
   這個訊號只用來表示套介面接受到緊急或者帶外資料時使用,參看後面的網路編程的部分。
   int SIGPOLL
   系統v的訊號,和SIGIO相似,只是為了相容的目的才設立。

11.2.5 作業控制訊號
   這一組訊號用來支援作業控制,一般情況下,你可以不用管這些訊號,採用系統預設的行為就可以了,除非你確切知道該怎樣控製作業系統的工作。
   int SIGCHLD
   當一個子進程結束時,就會向父進程發送該訊號。該訊號的預設行為是忽略,當進程建立起一個處理該訊號的函數控制代碼,並且這是已經有zombie進程存在,那麼是否產生該訊號由系統決定。
   int SIGCLD
   訊號SIGCHLD的舊名稱。
   int SIGCONT
   這個訊號的作用是當進程被停止後使進程繼續執行,而不做任何其他的工作。你不能阻塞該訊號,但是你可以為該訊號設定一個處理函數控制代碼,它總是使進程無條件 的執行下去。大多數程式沒有理由控制該訊號,它們只是簡單的繼續被中斷的操作。你可以利用該處理函數的控制代碼完成一些你需要的特殊工作,比如,重新列印一些 提示資訊,如果程式是因為等待輸入而被掛起的話。
   int SIGSTOP
   該訊號停止一個進程,它不能被控制、忽略和阻塞。
   int SIGTSTP
   這是一個互動停止訊號。不象SIGSTOP,它可以被控制或忽略。當你從控制台輸入SUSP字元(Ctrl-z)時,就會產生該訊號。
   int SIGTTIN
   當一個進程在後台執行時,它不能從使用者的終端中讀入任何輸入。當一個後台進程試圖從使用者終端讀時,所有進程都會接受到一個SIGTTIN訊號。該訊號的預設操作是停止進程,從而讓需要輸入的後台進程能夠到前台讀入需要的輸入資訊。
   int SIGTTOU
   它和SIGTTIN相似,只是發生在後台進程寫終端時。
   當一個進程停止時,任何訊號都不會再傳遞給它,除了SIGKILL和SIGCONT訊號(顯然),所有給它的訊號標記為未定的(pending),並且只 有當進程重新進入執行狀態時才得到最終傳遞。SIGKILL訊號總是迫使進程結束,而且不能阻塞、忽略和控制。你可以忽略SIGCONT訊號,但是它總是 能夠使被停止的進程繼續執行。一個SIGCONT訊號可以讓所有未定的停止訊號被丟棄,類似的,一個停止訊號能讓未定的SIGCONT訊號丟棄。

11.2.6 操作錯誤訊號
   這組訊號都是由進程的操作錯誤引起的,他們不必是程式的錯誤,而是任何阻止操作完成的錯誤。這些訊號的預設操作是中止進程的執行。
   int SIGPIPE
   如果你使用管道或者FIFO進行進程間的通訊,你必須讓你的應用程式在寫入一個管道之前先有一個程式已經開啟了該管道並且已經開始讀取資料。如果這時沒有 開始,或者讀管道的進程意外退出了,那麼寫操作就會產生一個SIGPIPE訊號。如果SIGPIPE訊號被阻塞、控制或忽略,那麼寫操作將返回錯誤,錯誤 代碼是EPIPE。更進一步的資訊參見後面的相關章節。
   int SIGLOST
   該訊號表明資源的丟失,在GNU系統中,通常任何提供服務的伺服器意外死機,都能引起該訊號。一般忽略該訊號並無不妥,因為和這種操作相關的錯誤都能使相關函數返回錯誤。
   int SIGXCPU
   CPU時間限制到。該訊號表明對進程使用的CPU時間的限制已經達到。
   int SIGXFSZ
   該訊號表明進程試圖增長檔案超過系統對檔案長度的限制。

11.2.7 外圍訊號
   這組訊號用於各種各樣的目的,一般不會影響進程的執行。
   int SIGUSR1
   int SIGUSR2
   這兩個訊號可以用來完成你希望的任何目的,通常用來進行網路通訊。如果你在一個進程裡有用來接受該訊號的程式,你的另外的進程就可以發送訊號給相應的進程。這個訊號的預設操作是終止進程的執行。
   int SIGWINCH
   系統終端的每屏行數和列數發生改變時發送該訊號。它的預設操作是忽略。如果是一個全螢幕輸出的程式則需要控制該訊號,根據新的每屏行和列數重新初始化輸出。
   int SIGINFO
   該訊號可以由控制台通過鍵盤發送給所有前台進程組的進程。如果接收訊號的進程是領頭進程,那麼它一般會列印一些系統資訊和進程的一些當前資訊,如果是其他進程,那麼預設情況下不會做任何事情。

11.2.7 訊號訊息
   我們上面提到的標準訊號都可以用一個系統提供的字串描述。我們用函數strsignal()和psignal()來擷取相關的字串。
   char * strsignal(int signum)
   該函數返回一個已經分配好的靜態字串,用來描述signum訊號相關的文字資訊。你無權修改這個返回的字串,並且,既然在另外的調用中能夠重寫該字元 串,如果你需要在後面的程式中使用,必須自己儲存該字串的備份。該函數是GNU系統的擴充,它的原型包含在string.h標頭檔中。
   void psignal(int signum, const char *message)
   該函數輸出一個描述signum訊號的訊息到標準錯誤輸出。如果傳遞該函數的message是一個NULL指標或空串,這個函數只列印和訊號相關的標準的 訊息。如果你傳遞給函數非空的message參數,那麼系統會先輸出message字串,然後輸出相關訊息。該函數在signal.h檔案中聲明。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.