1. 程式人生 > 實用技巧 >在kernel space monitor 系統呼叫來觀察userspace程序的行為。

在kernel space monitor 系統呼叫來觀察userspace程序的行為。

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,enum
pid_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都是相同(新)編號。

當一個執行緒啟動另一個執行緒時,

該啟動的執行緒會獲得其自己的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