從Linux 0 11核心看Linux訊號處理機制

2021-06-12 00:08:42 字數 2932 閱讀 8502

摘要:

訊號處理機制是unix作業系統的一大特點。本文以linux0.11訊號處理相關原始碼為例,針對幾個細節對訊號處理的整個流程進行描述,力求簡單明瞭,參考趙炯博士的《linux核心完全剖析》和潘曉雷的《linux0.11原始碼分析》。

所謂訊號,是一種軟中斷機制,是實現程序間非同步通訊的手段。訊號的傳送和處理是非同步的,程序並不知道什麼時候會收到訊號。訊號同中斷很像,不同的訊號對應不同的訊號型別,並且對應不同的訊號型別有相應的訊號處理函式和訊號遮蔽位。

程式錯誤:除零,非法記憶體訪問…

外部訊號:終端ctrl-c產生sgint訊號,定時器到期產生sigalrm…

顯式請求:kill函式允許程序傳送任何訊號給其他程序或程序組。

在linux下,可以通過以下命令檢視系統所有的訊號:

kill -l

可以通過類似下面的命令顯式的給乙個程序傳送乙個訊號:

kill -2 pid

忽略訊號:大部分訊號可被忽略,除sigstop和sigkill訊號外(這是超級使用者殺掉或停掉任意程序的手段)。

捕獲訊號:註冊訊號處理函式,它對產生的特定訊號做處理。

讓訊號預設動作起作用:unix核心定義的預設動作,有5種情況:

a) abort:終止程序並產生core檔案。

b) stop:終止程序但不生成core檔案。

c) 忽略:忽略訊號。

d) suspend:掛起程序。

e) continue:若程序是掛起的,則resume程序,否則忽略此訊號。

當前程序由於系統呼叫、中斷或異常而進入核心態以後,從核心態返回到使用者態之前。

當前程序在核心中進入睡眠以後剛被喚醒的時候(必定是在系統呼叫中),或者由於不可忽略訊號的存在而提前返回到使用者空間。

用於儲存訊號資訊的結構體

struct sigaction ;
程序結構體重關於訊號的定義

do_signal()函式 引數為核心態堆疊中的內容

void do_signal(long signr,long eax, long ebx, long ecx, long edx,

long fs, long es, long ds,

long eip, long cs, long eflags,

unsigned long * esp, long ss)

if (sa->sa_flags & sa_oneshot)

sa->sa_handler = null;

*(&eip) = sa_handler;

longs = (sa->sa_flags & sa_nomask)?7:8;

*(&esp) -= longs;

verify_area(esp,longs*4);

tmp_esp=esp;

put_fs_long((long) sa->sa_restorer,tmp_esp++);

put_fs_long(signr,tmp_esp++);

if (!(sa->sa_flags & sa_nomask))

put_fs_long(current->blocked,tmp_esp++);

put_fs_long(eax,tmp_esp++);

put_fs_long(ecx,tmp_esp++);

put_fs_long(edx,tmp_esp++);

put_fs_long(eflags,tmp_esp++);

put_fs_long(old_eip,tmp_esp++);

current->blocked |= sa->sa_mask;

}

對核心態堆疊的修改

通過上述內容,可以看到作業系統在檢測到有訊號傳入時,首先把核心堆疊中存放返回執行點的eip(指令暫存器)儲存為old_eip,然後將eip替換為訊號處理函式的位址,然後將核心中儲存的「原esp」(即使用者態棧位址)減去一定的值,目的是擴大使用者態的棧,然後將核心棧上的內容儲存到使用者棧上。

之所以把eip的值設定成訊號處理函式的位址,是因為一旦程序返回使用者態,就要去執行訊號處理程式,所以eip要指向訊號處理程式而不是原來應該執行的位址。

在前面介紹sigaction資料結構的時候出現了訊號活動恢復函式指標sa_restroer,該指標主要用於使用者態堆疊的清理,把系統呼叫後的返回值eax和暫存器ecx,edx以及標誌暫存器eflags彈出,完全恢復系統呼叫後各暫存器和cpu的狀態,最後通過ret指令彈出原使用者程式的eip(即堆疊中的old_eip),返回執行使用者程式。

但是在linux核心**中,並沒有 給出此函式的具體定義,檢視相關資料,在linux的libc函式庫中定義有函式如下

編譯程式在編譯連線使用者自定義的訊號處理函式時,會將sa_restorer()函式插入到使用者程式中。這樣,使用者在處理完自定義的訊號處理函式後,就會繼續執行使用者**了。、

Linux 0 11 核心筆記

1 任務0的堆疊問題 一直不明白schedule.c裡的task union的stack和user stack是什麼關係,head.s裡就設定了esp指向user stack,卻一直沒有用到task union,直到看到init task才明白,從進入保護模式到跳轉進使用者態都是用的user sta...

Linux0 11核心筆記( )

c語言 彙編知識 嵌入式彙編 x86處理器和程式設計的相關知識和 unix作業系統設計 linus在最初開發linux作業系統時參考了minix作業系統 作業系統 設計與實現 一種基於訊息傳遞在核心各模組之間進行通訊 資訊交換 重要的五個支柱 unix作業系統 分時作業系統 minix作業系統 gn...

Linux 0 11核心編譯問題

弄了好長時間,只是可以用linux 0.11我的linux實驗室環境,使用bochs模擬,進入linux 0.11 cd cd src linux make 這樣就編譯成image了 mkdir a mkdir a boot mcopy image a boot 將映象檔案拷貝到啟動軟盤 修改men...