在kernel space monitor 系統呼叫來觀察userspace程序的行為。
阿新 • • 發佈:2020-11-05
1.簡介
近期遇到在userspace的程序隨機關閉fd 0的問題,最後導致其他程序使用fd 0時出現coredump。
如果能夠在close系統呼叫中檢查所有的程序呼叫close時,通過傳入引數是否為0來找出問題,會比較方便。
2.做法
a.out是我們需要monitor的程序,因為它可能是執行緒,所以我們通過tgid來找到程序的pid。
通過struct_tast *tsk;來獲取程序的task,最後發訊號也是給程序。
1 if (fd == 0){ 2 tsk = pid_task(find_pid_ns(tid, task_active_pid_ns(current)), PIDTYPE_PID);3 pr_err("DENNIS: fd 0 is be close for %s-%d tid %d tsk %s\n", current->comm, current->pid, current->tgid, tsk->comm); 4 if (!strncmp(tsk->comm, "a.out", sizeof("a.out"))){ 5 extern int do_send_sig_info(int sig, struct siginfo *info, struct task_struct *p,enumpid_type type); 6 do_send_sig_info(SIGABRT, SEND_SIG_FORCED, tsk, true); 7 } 8 }
3.看到stackoverflow中介紹pid與tgid比較好的介紹,這裡直接貼上來了。
在核心中,每個執行緒都有自己的ID,稱為PID(儘管將其稱為TID或執行緒ID可能更有意義),並且它們還具有TGID(執行緒組ID),它是執行緒的PID這開始了整個過程。
簡而言之,當建立一個新程序時,它顯示為一個執行緒,其中PID和TGID都是相同(新)編號。
當一個執行緒啟動另一個執行緒時,
這樣,核心可以愉快地排程執行緒,而與執行緒所屬的程序無關,而將程序(執行緒組ID)報告給您。
以下執行緒層次結構可能會有所幫助(a):
USER VIEW
<-- PID 43 --> <----------------- PID 42 ----------------->
+---------+
| process |
_| pid=42 |_
_/ | tgid=42 | \_ (new thread) _
_ (fork) _/ +---------+ \
/ +---------+
+---------+ | process |
| process | | pid=44 |
| pid=43 | | tgid=42 |
| tgid=43 | +---------+
+---------+
<-- PID 43 --> <--------- PID 42 --------> <--- PID 44 --->
KERNEL VIEW
您可以看到,啟動一個新程序(左側)會為您提供一個新的PID和一個新的TGID(兩者都設定為相同的值),而啟動一個新執行緒(右側)會為您提供一個新的PID,同時保持相同的值TGID作為啟動它的執行緒。
4.列一下Linux的訊號。
SIGHUP 1 /* Hangup (POSIX). */ 終止程序 終端線路結束通話 SIGINT 2 /* Interrupt (ANSI). */ 終止程序 中斷程序 Ctrl+C SIGQUIT 3 /* Quit (POSIX). */ 建立CORE檔案終止程序,並且生成core檔案 Ctrl+\ SIGILL 4 /* Illegal instruction (ANSI). */ 建立CORE檔案,非法指令 SIGTRAP 5 /* Trace trap (POSIX). */ 建立CORE檔案,跟蹤自陷 SIGABRT 6 /* Abort (ANSI). */ SIGIOT 6 /* IOT trap (4.2 BSD). */ 建立CORE檔案,執行I/O自陷 SIGBUS 7 /* BUS error (4.2 BSD). */ 建立CORE檔案,匯流排錯誤 SIGFPE 8 /* Floating-point exception (ANSI). */ 建立CORE檔案,浮點異常 SIGKILL 9 /* Kill, unblockable (POSIX). */ 終止程序 殺死程序 SIGUSR1 10 /* User-defined signal 1 (POSIX). */ 終止程序 使用者定義訊號1 SIGSEGV 11 /* Segmentation violation (ANSI). */ 建立CORE檔案,段非法錯誤 SIGUSR2 12 /* User-defined signal 2 (POSIX). */ 終止程序 使用者定義訊號2 SIGPIPE 13 /* Broken pipe (POSIX). */ 終止程序 向一個沒有讀程序的管道寫資料 SIGALARM 14 /* Alarm clock (POSIX). */ 終止程序 計時器到時 SIGTERM 15 /* Termination (ANSI). */ 終止程序 軟體終止訊號 SIGSTKFLT 16 /* Stack fault. */ SIGCLD SIGCHLD /* Same as SIGCHLD (System V). */ SIGCHLD 17 /* Child status has changed (POSIX). */ 忽略訊號 當子程序停止或退出時通知父程序 SIGCONT 18 /* Continue (POSIX). */ 忽略訊號 繼續執行一個停止的程序 SIGSTOP 19 /* Stop, unblockable (POSIX). */ 停止程序 非終端來的停止訊號 SIGTSTP 20 /* Keyboard stop (POSIX). */ 停止程序 終端來的停止訊號 Ctrl+Z SIGTTIN 21 /* Background read from tty (POSIX). */ 停止程序 後臺程序讀終端 SIGTTOU 22 /* Background write to tty (POSIX). */ 停止程序 後臺程序寫終端 SIGURG 23 /* Urgent condition on socket (4.2 BSD). */ 忽略訊號 I/O緊急訊號 SIGXCPU 24 /* CPU limit exceeded (4.2 BSD). */ 終止程序 CPU時限超時 SIGXFSZ 25 /* File size limit exceeded (4.2 BSD). */ 終止程序 檔案長度過長 SIGVTALRM 26 /* Virtual alarm clock (4.2 BSD). */ 終止程序 虛擬計時器到時 SIGPROF 27 /* Profiling alarm clock (4.2 BSD). */ 終止程序 統計分佈圖用計時器到時 SIGWINCH 28 /* Window size change (4.3 BSD, Sun). */ 忽略訊號 視窗大小發生變化 SIGPOLL SIGIO /* Pollable event occurred (System V). */ SIGIO 29 /* I/O now possible (4.2 BSD). */ 忽略訊號 描述符上可以進行I/O SIGPWR 30 /* Power failure restart (System V). */ SIGSYS 31 /* Bad system call. */ SIGUNUSED 31
來源:https://www.cnblogs.com/frisk/p/11602973.html
5.程序如何接受訊號。
可以參考之前的介紹:https://www.cnblogs.com/smilingsusu/p/12845474.html