linux信号以及core

何为信号

信号(signal)用于通知进程发生了某种情况。进程有以下3种处理信号的方式:

  1. 忽略信号。有些信号表示硬件异常,例如,除以0或访问进程地址空间以外的存储单元等,因为这些异常产生的后果不确定,所以不推荐使用这种处理>方式。
  2. 按系统默认方式处理。对除数为0,系统默认方式是终止进程。
  3. 提供一个函数,信号发生时调用该函数,这被称为捕抓该信号。通过提供自编的函数,我们就能知道什么时候产生了信号,并按期望的方式处理它。

以上摘自《APUE》中文版14页

信号类型

[root@test ~]# kill -l1) SIGHUP  2) SIGINT   3) SIGQUIT  4) SIGILL   5) SIGTRAP6) SIGABRT    7) SIGBUS   8) SIGFPE   9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG  24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF 28) SIGWINCH    29) SIGIO   30) SIGPWR
31) SIGSYS  34) SIGRTMIN    35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10    45) SIGRTMIN+11    46) SIGRTMIN+12    47) SIGRTMIN+13
48) SIGRTMIN+14    49) SIGRTMIN+15    50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX

每个信号有其默认的处理方式,参考manpage,分为以下几种类型

Term Default action is to terminate the process.

Ign Default action is to ignore the signal.

Core Default action is to terminate the process and dump core (see
core(5)).

Stop Default action is to stop the process.

Cont Default action is to continue the process if it is currently
stopped.

例如我们常用的kill的默认信号SIGTERM(15),以及强制结束信号SIGKILL(9),其对应的处理方式都是Term,我们经常使用SIGABRT(6)对应处理方式是Core,可以用来产生core-dump文件

core文件详解

core文件是ELF-formatted文件,可以使用readelf查看core的elf信息。它包含了程序运行时的内存,寄存器状态,堆栈指针,内存管理信息等

配置coredump

  • 开启coredump
# 开启coredump
ulimit -c unlimited
# 持久化方式
echo "ulimit -c unlimited" >> /etc/profile
  • 设置coredump的命名规则
# 在/etc/sysctl.conf文件中加入
# 例如下面这个命令,可以通过在%e前面增加/home/之类的路径使其保存到特定路径
kernel.core_pattern=%e.core.%s_%t
并保存退出,执行下面指令使其生效
sysctl -p# 参数含义%%  output one '%'%p  pid%u  uid%g  gid%s  signal number%t  UNIX time of dump%h  hostname%e  executable filename# 默认是这样的 |/usr/share/apport/apport %p %s %c %PIf the first character of the pattern is a '|', the kernel will treatthe rest of the pattern as a command to run.  The core dump will bewritten to the standard input of that program instead of to a file.
  • 通过cat /proc/sys/kernel/core_pattern 验证设置的pattern
  • 每个进程也可以通过setrlimit的RLIMIT_CORE配置进程级别的core大小

控制coredump的mapping

/proc/[pid]/coredump_filter可以指定怎样的进程空间内存可以保存到core文件里,它是由下面的bitmask组成

  • (bit 0) anonymous private memory(匿名私有内存段,例如:动态变了)
  • (bit 1) anonymous shared memory(匿名共享内存段)
  • (bit 2) file-backed private memory(file-backed 私有内存段)
  • (bit 3) file-backed shared memory(file-bakced 共享内存段,例如:动态链接库)
  • (bit 4) ELF header pages in file-backed private memory areas (it is effective only if the bit 2 is cleared)(ELF 文件映射,只有在bit 2 复位的时候才起作用)
  • (bit 5) hugetlb private memory(大页私有内存)
  • (bit 6) hugetlb shared memory(大页共享内存)
  • bit 7 (since Linux 4.4) Dump private DAX pages.
  • bit 8 (since Linux 4.4) Dump shared DAX pages.

默认配置是0x33,也就是说bits 0 (anonymous private mappings), 1 (anonymous shared mappings), 4 (ELF headers) and 5 (private huge pages) 都会被dump出。如果想改变bitmask,可以使用如下方法:

echo 0x00000001 > /proc/[pid]/coredump_filter

也可以配置在当前shell生效的coredump_filter

# 如果没有下面的文件,请检查内核参数CONFIG_ELF_CORE是否配置
$ echo 0x7 > /proc/self/coredump_filter
$ ./some_program

注意:

  1. 如果你想设置全局的coredump_filter,可以参考这篇文章
  2. MMIO的页永远不会被dump出来

产生core-dump的方法

  1. 发信号SIGABRT,会终止进程
  2. gcore,gcore会调用gdb产生coredump,不会终止进程,但是产生core的时候进程会处于stopped状态
  3. 设置信号处理函数,信号处理函数fork()abort()
  4. google-coredumper上述的方法1终止进程,方法2会暂停进程,所以谷歌就做了个coredump库,支持在运行时coredump

gcore

  • gcore实际上就是gdb里面的一个命令,它的作用是把进程的memory全部dump出来,和系统调用abort()等方法的实现方式是不同的。最直观的感受是gcore会把进程全部的VIRT内存dump出来。产生的core文件有可能会很大,并且它的大小不受ulimit -c限制。
  • 使用gcore dump出的core文件,在gdb中使用info files查看每段内存的大小,比使用abort()dump出的要大的多,原因应该是gcore把没有用到的虚拟内存也dump出来了
  • gcore执行过程中程序处于stopped状态
  • 命令行中的gore命令其实是RedHat linux制作的一个shell script用来调用gdb,所以如果你调用了命令行gcore [pid],它实际上会执行如下的gdb命令,如下,以进程40923为例:
gdb --nx --batch -ex set pagination off -ex set height 0 -ex set width 0 -ex attach 40923 -ex gcore core.40923 -ex detach -ex quit

所以,如果你没有gcore命令,也可以使用如下命令产生gcore

gdb --pid=40923 --batch -ex gcore

signal 函数

  1. 信号处理函数signal 规定了在某种信号signo情况下调用func处理
  2. 正在处理的时候,其他信号是不能递交的,必须等当前信号处理完毕,其他信号才能递交
#include <signal.h>
typedef void Sigfunc(int);
Sigfunc *signal(int signo, Sigfunc *func)

SIGCHLD

  1. 子进程终止时,会给父进程发一个SIGCHLD信号(其实这个信号是由内核在进城终止时发给父进程的(《UNIX网络编程》P103)),如果父进程不处理的话,子进程机会变成僵尸进程
  2. 父进程只需要在信号处理函数里面调用wait即可。
  3. 如果不想子进程产生僵尸进程,可以设置SIG_IGN
     signal(SIGCHLD, SIG_IGN);
    
signal(SIGCHLD, sig_chld);void
sig_chld(int signo)
{pid_t  pid;int     stat;pid = wait(&stat);printf("child %d terminated\n", pid);return;
}

僵尸进程的危害

所谓僵尸进程,形象来说,进程已死,但其尸体还在,没人收尸啊,冤魂不散,仍然占用一个进程号,如果主进程不妥善处理,当僵尸进程数量巨大之后,就没法再次fork了,所以对于大型并发服务器来说,当建立了进程池,一定要想办法处理掉所有僵尸进程。

SIGPIPE

《UNP》中文版113页

  1. A与B连接, B异常终止了,这是B会终止socket连接并且给A发一个fin,
  2. 这时如果A再给B发一个写, B的套接字会回一个RST
  3. 如果A再再给B发一个写, 会引发SIGPIPE信号, 这个信号试图终止进程A, 如果A不情愿被终止,那么必须signal捕获该信号并处理,但是无论如何,写操作都会fail并且errno=EPIPE
  4. signal函数最简单的方法就是把SIGPIPE置成SIG_IGN,这样进程就会忽略SIGPIPE信号。
signal(SIGPIPE, SIG_IGN);

SIGIO

信号驱动式I/O模型, 利用信号,让内核在描述符就绪时发送SIGIO信号通知进程

其他相关函数

sigation

  • 在一些较早的系统上(《UNP》P105),signal设置的信号句柄只能起一次作用,信号被捕获一次后,信号句柄就会被还原成默认值了。我们现在用的linux系统应该没有关系的
  • sigaction设置的信号句柄,可以一直有效,直到你再次改变它的设置。
struct sigaction sa;
sa.sa_handler = SIG_IGN;
sigaction( SIGPIPE, &sa, 0 );

sigation的定义:

struct sigaction {void     (*sa_handler)(int);void     (*sa_sigaction)(int, siginfo_t *, void *);sigset_t   sa_mask;int        sa_flags;  // 一般置0, 有一些特殊的标志位会用到这个, 如SA_NOCLDSTOP等void     (*sa_restorer)(void);
};

wait和waitpid函数

wait 函数可以用来处理已终止的子进程

#include <sys/wait.h>
pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc, int options);  // 成功返回进程ID, 出错返回0或-1
  1. 通过返回,返回已终止子进程的ID
  2. 通过statloc指针返回子进程终止状态

waitpid()

《UNIX网络编程》 P110

通过waitpid设置WNOHANG选项,可以告知waitpid在有尚未终止的子进程在运行时不要阻塞

参考链接

  1. Linux信号(一):信号类型
  2. What’s the easiest way to detect what signals are being sent to a process?
  3. signal(7) — Linux manual page信号的不同用处
  4. core(5) — Linux manual page
  5. 线上内存泄漏的正确查找姿势

linux信号以及core相关推荐

  1. linux 信号 core,Shell 信号发送与捕捉

    原标题:Shell 信号发送与捕捉 作者:李振良OK 1.Linux信号类型 信号(Signal):信号是在软件层次上对中断机制的一种模拟,通过给一个进程发送信号,执行相应的处理函数. 进程可以通过三 ...

  2. linux信号(signal) 机制分析

    1       信号本质 软中断信号(signal,又简称为信号)用来通知进程发生了异步事件.在软件层次上是对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的. ...

  3. linux下调试core dump方式汇总,工作必备技能

    缘起 调试,是开发流程中一个非常重要的环节.每个程序员都应,具备调试代码的能力,尤其对于从事 Linux 下的开发的读者. 从事 linux 下后台开发,有时候会遇到程序突然崩溃的情况,也没有任何日志 ...

  4. Linux信号 一 信号可靠性与分类

    开发SNMP的时候用到了Linux信号机制,总结了一下关于信号的知识. 信号是一种进程间通信手段,本质是一种软件中断,用来处理异步事件.信号机制是Unix家族里一个古老的通信机制.传统的信号机制有一些 ...

  5. 非常好的一篇对linux信号(signal)的解析

    [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核对于信号的处理流程包括信号的触发/注册/执 ...

  6. 【Linux系统编程】Linux信号列表

    00. 目录 文章目录 00. 目录 01. Linux信号编号 02. 信号简介 03. 特殊信号 04. 附录 01. Linux信号编号 在 Linux 下,每个信号的名字都以字符 SIG 开头 ...

  7. Linux 信号(signal)

    目录 1 信号的本质 2 信号列表 3 信号发送时机 3.1 内核自动给进程发送信号 3.2 进程给进程发送信号 4 信号处理时机 5 统一事件源 1 信号的本质 软中断信号(signal,又简称为信 ...

  8. linux signal用法,Linux 信号 signal 用法详解及注意事项

    Linux 信号 signal 用法详解及注意事项 1) SIGHUP 本信号在用户终端连接 (正常或非正常) 结束时发出, 通常是在终端的控 制进程结束时, 通知同一 session 内的各个作业, ...

  9. Linux:生成core的几种方式

    Linux:生成core的几种方式 1.总结 在某些情况下,进程会生成core文件(核心转储),记录进程状态,帮助我们快速定位异常. 例如: 当进程异常时如段错误退出,可以分析结果core,查看调用栈 ...

最新文章

  1. 卸载sharepoint2013
  2. 轻松理解https,So easy!
  3. java Poi导入exel表格的数据,入库
  4. django开发 遇到的问题解决
  5. python实现新闻网站_Python 教你 4 行代码开发新闻网站通用爬虫
  6. docker 部署rabbitmq,k8s部署rabbitmq集群,跟踪和监控rabbitmq
  7. 输入输出运算符的重载
  8. 190416每日一句
  9. 【Android】用MediaRecorder录制视频太短崩的问题
  10. crossentropyloss 输入_Pytorch常用的交叉熵损失函数CrossEntropyLoss()详解
  11. 86年版五笔和98年版五笔区别
  12. 使用python基于git log统计开发代码量
  13. 华硕笔记本键盘突然个别键失灵
  14. 【Windows 问题系列第 7 篇】电脑卡跟C盘容量有关系吗?
  15. 机器学习背后的数学:范数与赋范空间
  16. NDK Resolution Outcome: Project settings: Gradle model version=XXX, NDK version is UNKNOWN
  17. 八、血条的制作和boss敌人的产生(雷霆战机)
  18. 制药机械设备远程监控及故障预警维护管理系统
  19. vue移动端网页适配
  20. 北京交通拥堵问题及其建议

热门文章

  1. 1.OD-破解MTS DashBoard
  2. 逆向工程核心原理读书笔记-API钩取之IE浏览器连接控制
  3. 透过汇编另眼看世界之DLL导出函数调用
  4. STL 之随机访问迭代器
  5. LXC C API 使用
  6. 小白如何学习大神的小项目
  7. 互联网公司常用分库分表方案汇总
  8. Nebula:Slack 的覆盖全球性的开源网络
  9. 英特尔QSV技术在FFmpeg中的实现与使用
  10. C/C++学习之路_六: 指针