• 在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
    ", 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. 看到 stack overflow中介绍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

  • 相关阅读:
    BERT模型fine-tuning代码解析(一)
    使用BERT获取中文词向量
    使用BERT获取中文词向量
    中文情感分类任务如何对bert语言模型微调,微调后的模型如何使用
    Tencent_AILab_ChineseEmbedding使用(×××××)
    中文自然语言处理数据集
    Anaconda环境的创建/激活/删除/管理
    thymeleaf和vue的关系
    模拟测试20191013
    模拟测试20191011-2
  • 原文地址:https://www.cnblogs.com/smilingsusu/p/13933562.html
Copyright © 2020-2023  润新知