成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

玩透Linux信號機制

系統 Linux
syscall進入內核,把該干的事情干完,就執行sysret返回用戶態。返回到哪里?rcx中內存地址的位置,這個位置就是信號處理函數。執行完信號處理函數,pop出棧底元素,跳過去,這個位置就是CPU執行syscall進入內核后面的哪一行代碼的內存地址,從而實現接著執行。

1.信號處理函數

如果我們想捕捉進程的這兩個信號:SIGCHLD、SIGCONT,用到函數sigaction

圖片圖片

Linux內核提供了多少種信號呢?shell終端運行shell -l即可看到,64種。我們代碼中捕捉的兩個信號,分別是17號、18號信號,這兩個數字記一下,等下查看內核數據能看到

圖片圖片

先在內核中找到我們注冊的信號處理函數,再說底層實現原理。這個你得自己寫內核驅動程序,市面上沒有任何工具可以讓你看

圖片圖片

找到了。再確定一下我們通過函數sigaction注冊的信號處理函數地址是不是這兩個,一毛一樣

圖片圖片

接下來說說Linux內核是如何存儲我們注冊的信號處理函數

struct task_struct {
    struct sighand_struct		*sighand;
    ……
}

struct sighand_struct {
	spinlock_t		siglock;
	refcount_t		count;
	wait_queue_head_t	signalfd_wqh;
	struct k_sigaction	action[_NSIG];
};

struct k_sigaction {
	struct sigaction sa;
#ifdef __ARCH_HAS_KA_RESTORER
	__sigrestore_t ka_restorer;
#endif
};

struct sigaction {
#ifndef __ARCH_HAS_IRIX_SIGACTION
	__sighandler_t	sa_handler;
	unsigned long	sa_flags;
#else
	unsigned int	sa_flags;
	__sighandler_t	sa_handler;
#endif
#ifdef __ARCH_HAS_SA_RESTORER
	__sigrestore_t sa_restorer;
#endif
	sigset_t	sa_mask;	/* mask last for extensibility */
};

Linux內核中,每個進程對應一個task_struct實例,里面有個屬性sighand就是用來存儲你使用函數sigaction注冊的信號處理函數,具體存儲在sighand_struct的action數組中,數組的索引就是信號的編號:1-64,數組的值是k_sigaction實例,真正存放信號處理函數的地方是sigaction.sa_handler

所以如果你想查看Linux內核中,某個進程注冊的所有信號處理函數,代碼這樣寫即可

圖片圖片

至此,我們寫代碼注冊的信號處理函數,在內核中如何存儲的,就徹底搞明白了。那內核是何時、怎么調用這個函數的呢?接著走……

2.kill-18

比如我們通過kill -18向進程18226發送信號,中間發生了什么?我就不貼源碼了,直接單步調試內核,貼調用棧吧

圖片圖片

這里看到的只是內核態的調用棧,用戶態的,kill命令底層調用的就是glibc庫中的kill函數,而kill函數則是通過syscall+kill的內核調用號,進入內核,調用相關函數

圖片圖片

關于用戶態切內核態,CPU提供了四個門、兩個快速調用,以前的實現方式是0x80中斷門,現在都是走syscall快速調用。如果你非科班,或者沒學過操作系統,應該沒聽過這個,或者對這個沒概念。建議非科班出身的小伙伴,一定要把操作系統補一下

那這個信號在內核中是如何存儲的呢?核心邏輯在send_signal中,我就不貼代碼了,直接說它做了什么吧

struct task_struct {
    struct signal_struct		*signal;
    sigset_t			blocked;
    ……
}

struct signal_struct {
    /* shared signal handling: */
	struct sigpending	shared_pending;
    ……
}

struct sigpending {
	struct list_head list;
	sigset_t signal;
};

struct sigqueue {
	struct list_head list;
	int flags;
	kernel_siginfo_t info;
	struct user_struct *user;
};

進入內核的時候,信號會被包裝成kernel_siginfo

圖片圖片

真正與進程關聯起來的步驟是,將kernel_siginfo再包裝成sigqueue,然后將sigqueue實例掛到sigpending中,進程結構體task_struct中有個屬性shared_pending就是鏈表頭,有點抽象,看圖

圖片圖片

順便說一下,Linux內核中的64種信號分成兩個陣營:可靠信號與不可靠信號,可靠信號又叫實時信號,不可靠信號又叫非實時信號

圖片圖片

實時與非實時,表達的不是立刻去做的意思,是指信號不會丟失。這名字起的真讓人容易產生誤解。Linux內核中的很多函數名也是,比如get_signal,它里面做了很多重要的事情,我看代碼的時候以為就是去信息相關信息

嗯,差不多就這些。至此,信號在內核中是如何存儲的就清晰了。那進程何時處理信號,Linux內核是如何設計的呢?

3.信號處理

如果這塊由你來設計,你會怎么做?不知道?好吧……

Linux內核是如何設計的呢?它的設計是在進程由內核態返回用戶態的路徑上實現的。為什么要這么做呢?

因為要兼容運行用戶態注冊的信號處理函數,這個節點是最優選擇。反正都要進入用戶態執行,在這之前,順便把信號處理函數執行了。這里要怎么實現呢?改線程棧結構,你如果學了我講的匯編,你就知道要怎么改了。

同樣,不貼代碼了,直接單步調試Linux內核看吧!

圖片圖片

函數do_signal就是信號處理的核心函數

接下來詳細分析代碼層面實現,如果你不會匯編,你可能就看不懂了

4.執行信號處理函數

什么時候CPU會由用戶態進入內核態呢?發生中斷、異常,還有比較常見的:系統調用。比如write函數

圖片圖片

當CPU執行syscall指令,CPU就進入Linux內核中了,這時候用戶態的棧比如是這樣(我就畫關鍵信息了哦)

圖片圖片

如果有信號需要處理的時候,這時候用戶又設置了信號處理函數,那內核在回用戶態前會把棧改成這樣

圖片圖片

會把rcx設置為信號處理函數的地址,syscall進入內核,配套的返回指令是sysret,會返回到rcx中內存地址的位置執行代碼。所有的函數的最后一條指令都是ret,會pop出棧頂元素,并跳轉到那個內存地址開始執行代碼。

syscall進入內核,把該干的事情干完,就執行sysret返回用戶態。返回到哪里?rcx中內存地址的位置,這個位置就是信號處理函數。執行完信號處理函數,pop出棧底元素,跳過去,這個位置就是CPU執行syscall進入內核后面的哪一行代碼的內存地址,從而實現接著執行。這樣就完成了進入用戶態,順便執行信號處理函數的動作。怎么樣,是不是特別有智慧!

責任編輯:武曉燕 來源: 硬核子牙
相關推薦

2011-07-05 18:40:19

QT 信號 機制

2011-07-05 18:32:52

QT 信號 機制

2025-02-03 07:00:00

2021-12-10 00:01:53

Vsync信號機制

2022-11-03 07:35:47

OS內核異步

2017-01-16 15:05:17

Linux信號機制分析

2017-01-16 14:48:42

Linux信號機制分析

2017-09-14 09:40:32

PythonUbuntu信號機制

2025-06-25 06:18:46

Linux多線程機制

2011-06-09 09:45:35

Linux QT 信號

2022-10-08 08:34:34

JVM加載機制代碼

2024-07-25 11:53:53

2010-09-09 14:15:08

無線網絡信號

2011-06-23 14:40:13

Qt 信號

2010-12-27 10:13:05

PROC文件系統

2009-11-23 19:47:57

ibmdwLinux

2024-05-08 13:41:31

OpenAIA/B測試

2016-08-16 08:26:19

Linuxsignalsigaction

2020-11-05 09:59:24

Linux內核信號量

2011-06-13 10:21:25

QT 信號 槽機制
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产农村一级国产农村 | 国产人成精品一区二区三 | 亚洲一区在线观看视频 | www.操.com| 亚洲色欧美另类 | 美女一级黄 | 亚洲一区二区三区国产 | 精品久久久久久亚洲精品 | 一级黄色片在线看 | 日本在线看| 粉嫩粉嫩芽的虎白女18在线视频 | 日韩成人| 99tv成人影院| 国产精品视频久久久久 | 91av视频在线免费观看 | 日日干夜夜草 | 欧美视频精品 | 亚洲精选久久 | 久久精品亚洲 | 欧美阿v | 日韩国产精品一区二区三区 | 精品亚洲一区二区三区 | 久久之精品| 精品1区 | 亚洲高清久久 | 成人小视频在线免费观看 | 中文字幕第十五页 | 国产成人精品久久 | 中文字幕视频在线观看 | 91久久精品一区二区二区 | 国产极品粉嫩美女呻吟在线看人 | 95国产精品 | 日韩一区二区av | 久久99这里只有精品 | 国产精品高清一区二区三区 | 国产区在线观看 | 亚洲欧美中文日韩在线v日本 | 日韩精品视频网 | 中文字幕亚洲欧美日韩在线不卡 | 97国产在线观看 | 日本在线一区二区 |