背景介绍

  Linux分为内核态和用户态,用户态通过系统调用(syscall)进入内核态执行。

  用户空间的glibc库将Linux内核系统调用封装成GNU C Library库文件(兼容ANSI & POSIX C语言标准),同时提供了其他特性的支持。

  应用程序通常不是直接调用Linux内核的系统调用接口,而是通过glibc库封装的接口间接调用Linux内核系统调用。

信号量机制

  关于Linux信号量机制的原理,建议阅读《Unix环境高级编程》第10章,本博客只是简单介绍其原理。

  信号量是一种软中断,用来实现Linux内核和应用程序之间的异步通信。

  每一个信号量由一个4字节整形数据表示。可以通过man 7 signal查看所有信号量描述。其中1~32号信号量是从Unix继承而来,33~64是Linux内核定义的信号量。

  Linux内核为每个信号量设置了默认处理动作,如Term(终止执行)、Ign(忽略)、Core(终止执行并产生coredump)、Stop(停止运行)和Cont(继续运行),当应用程序接收到某个信号量时,则按照默认处理动作执行。应用程序也可以通过sigaction()或者signal()函数修改默认的处理动作,比如屏蔽或者忽略某个信号量等。

  应用程序信号量处理函数通常是链接glibc中默认的信号量处理函数,也可以自己编写和指定信号量处理函数。但是需要注意的是,SIGKILL和SIGSTOP信号量不能被捕获(caught)、屏蔽(blocked)或者忽略(ignored)。

  信号量触发情况有三种:

  1)Linux内核检测到应用程序异常,发送特定的信号量给应用程序,应用程序捕获到信号量后,调用信号量处理函数;

  2)Linux内核因为内部事件而给应用程序发送特定信号,通知应用程序发生了某个事件,如著名的segmentation fault,应用程序捕获到信号量后,调用信号量处理函数;

  3)Linux内核检测到外部事件,如Ctrl+C,Ctrl+Z等,发送特定信号给应用程序,应用程序捕获到信号量后,调用信号量处理函数;

信号量列表

Signal Value Action Comment
SIGHUP 1 Term Hangup detected on controlling terminal or death of controlling process
SIGINT 2 Term Interrupt from keyboard
SIGQUIT 3 Core Quit from keyboard
SIGILL 4 Core Illegal Instruction
SIGTRAP 5 Core Trace/breakpoint trap
SIGABRT 6 Core Abort signal from abort(3)
SIGIOT 6 Core IOT trap. A synonym for SIGABRT
SIGEMT 7 Term  
SIGFPE 8 Core Floating point exception
SIGKILL 9 Term Kill signal, cannot be caught, blocked or ignored.
SIGBUS 10,7,10 Core Bus error (bad memory access)
SIGSEGV 11 Core Invalid memory reference
SIGPIPE 13 Term Broken pipe: write to pipe with no readers
SIGALRM 14 Term Timer signal from alarm(2)
SIGTERM 15 Term Termination signal
SIGUSR1 30,10,16 Term User-defined signal 1
SIGUSR2 31,12,17 Term User-defined signal 2
SIGCHLD 20,17,18 Ign Child stopped or terminated
SIGCONT 19,18,25 Cont Continue if stopped
SIGSTOP 17,19,23 Stop Stop process, cannot be caught, blocked or ignored.
SIGTSTP 18,20,24 Stop Stop typed at terminal
SIGTTIN 21,21,26 Stop Terminal input for background process
SIGTTOU 22,22,27 Stop Terminal output for background process
SIGIO 23,29,22 Term I/O now possible (4.2BSD)
SIGPOLL   Term Pollable event (Sys V). Synonym for SIGIO
SIGPROF 27,27,29 Term Profiling timer expired
SIGSYS 12,31,12 Core Bad argument to routine (SVr4)
SIGURG 16,23,21 Ign Urgent condition on socket (4.2BSD)
SIGVTALRM  26,26,28 Term Virtual alarm clock (4.2BSD)
SIGXCPU 24,24,30 Core CPU time limit exceeded (4.2BSD)
SIGXFSZ 25,25,31 Core File size limit exceeded (4.2BSD)
SIGSTKFLT 16 Term Stack fault on coprocessor (unused)
SIGCLD 18 Ign A synonym for SIGCHLD
SIGPWR 29,30,19 Term Power failure (System V)
SIGINFO 29   A synonym for SIGPWR, on an alpha
SIGLOST 29 Term File lock lost (unused), on a sparc
SIGWINCH 28,28,20 Ign Window resize signal (4.3BSD, Sun)
SIGUNUSED 31 Core Synonymous with SIGSYS

信号量进阶

  关于自定义信号量处理函数、屏蔽指定信号量等操作,参考《System Programing: Signals》

  信号量处理函数实质上是应用程序发生异常时的一种修复或者调试机制,因为信号量处理不是正常的函数调用,因此它会复用父函数的栈,如果信号量处理函数中发生了异常,系统是没有办法处理的,因此,信号量处理函数必须是安全可靠的。

  自定义的信号量处理函数不可以做信号量同步(防止死锁),但是可以通过call fork起gdb调试器或者写log文件到磁盘。

应用程序崩溃

  通常意义上讲,main()函数是应用程序的入口。但是实际上,Linux内核执行C程序时(通过exec函数),在调用main函数之前,先调用一个特殊的启动例程。可执行程序文件(ELF文件)将此启动例程指定为程序的起始地址。启动例程从内核取得命令行参数和环境变量值,为调用main函数做好准备。

  有8种方式使进程终止,其中5种为正常终止,他们是

  1) 从main返回(return语句)

  2) 调用exit

  3) 调用_exit或者_Exit

  4) 最后一个线程从其启动例程返回

  5) 最后一个线程调用pthread_exit

  异常终止有3种方式,他们是

  6) 调用abort()  ----SIGABRT

  7) 接收到一个信号量并终止    ---其他Term/Core类信号量

  8) 最后一个线程对取消请求做出响应

  由此可见,应用程序崩溃必然是因为内部或者外部的原因,导致内核发送信号量或者glibc主动触发信号量(abort),当应用程序捕获到信号量之后,进入异常处理流程。

Linux高级调试与优化——信号量机制与应用程序崩溃的更多相关文章

  1. Linux高级调试与优化——gdb调试命令

    番外 2019年7月26日至27日,公司邀请<软件调试>和<格蠹汇编——软件调试案例集锦>两本书的作者张银奎老师进行<Linux高级调试与优化>培训,有幸聆听张老师 ...

  2. Linux高级调试与优化——内存泄漏实战分析

    最近在整理Linux调试方面的文档,正好碰到了一个内存泄漏踩栈的问题,借此机会记录一下分析过程. 首先,发现问题之后,赶紧看一下产生coredump文件没有,果不其然,产生了coredump,果断上g ...

  3. Linux高级调试与优化——ptrace

    ptrace (process trace) #include <sys/ptrace.h> long ptrace(enum __ptrace_request request, pid_ ...

  4. Linux高级调试与优化——内存管理

    1.物理地址和虚拟地址 Linux采用页表机制管理内存,32位系统中页大小一般为4KB,物理内存被划分为连续的页,每一个页都有一个唯一的页号. 为了程序的的可移植性,进程往往需要运行在flat mem ...

  5. Linux高级调试与优化——用户态堆

    内存问题是软件世界的住房问题 嵌入式Linux系统中,物理内存资源通常比较紧张,而不同的进程可能不停地分配和释放不同大小的内存,因此需要一套高效的内存管理机制. 内存管理可以分为三个层次,自底向上分别 ...

  6. Linux高级调试与优化——同时抓取coredump和maps文件

    Linux内核源码 Documentation/sysctl/kernel.txt core_pattern: core_pattern: core_pattern is used to specif ...

  7. Linux高级调试与优化——进程管理和调度

    进程管理 进程和文件是Linux操作系统的两个最基本的抽象. 进程是处于执行期的程序,进程不仅仅局限于一段可执行程序代码,通常还包含其他资源,如打开的文件.挂起的信号.内核内部数据.处理器状态.进程地 ...

  8. Linux高级调试与优化——Address Sanitizer

    Address Sanitizer ASAN最早可以追溯到 LLVM 的 sanitizers项目(https://github.com/google/sanitizers),这个项目包含了Addre ...

  9. 09、高级编程之基于排序机制的wordcount程序

    package sparkcore.java; import java.util.Arrays; import java.util.Iterator; import org.apache.spark. ...

随机推荐

  1. vs2013在用户控件中添加jquery智能提示

    一.在script文件夹下面添加_references.js文件夹 二.把jquery文件拖到该文件中 保存,重新打开相应的文件,即出现智能提示

  2. 几个常用I/O函数用法(printf,fprintf等)

    一 格式化输出 1.printf 定义:int printf(const char *format,[argument]); 功能:产生格式化输出的函数(定义在 stdio.h 中) 参数说明:for ...

  3. 2019-11-29-VisualStudio-解决方案筛选器-slnf-文件

    title author date CreateTime categories VisualStudio 解决方案筛选器 slnf 文件 lindexi 2019-11-29 08:41:13 +08 ...

  4. php引用 & 详解

    在PHP 中引用的意思是:不同的名字访问同一个变量内容. 与C语言中的指针是有差别的.C语言中的指针里面存储的是变量的内容在内存中存放的地址 变量的引用 $a = 222; $b = &$a; ...

  5. 万兴神剪手 Wondershare Filmora v9.2.11.6 简体中文版

    目录 1. 介绍 2. 简体中文9.2.1.10汉化版下载 3. 安装和激活说明 1. 介绍 万兴神剪手 Filmora 是一款界面简洁时尚.功能强大的视频编辑软件,它是深圳万兴科技公司近年来的代表作 ...

  6. RHEL6本地YUM源配置

    1.挂载本地光盘到系统   1)通过光驱将系统盘挂载到某个目录 [root@cluster01 ~]# mkdir   /mnt/cdrom [root@cluster01 ~]# mount -t ...

  7. shell统计mysql当前连接数

    [root@push-- scripts]# mysql -S /var/lib/mysql//mysql.sock -uroot -phlsms_push_Zaq1xsw@ -e "sho ...

  8. php strip_tags() 函数去除 HTML、XML 以及 PHP 的标签。

    strip_tags() 函数剥去 HTML.XML 以及 PHP 的标签.strip_tags(string,allow)参数     描述string     必需.规定要检查的字符串.allow ...

  9. C语言实现栈代码

    /* 栈的特性:先进后出. 栈在计算语言处理和将递归算法改为非递归算法等方面起着非常重要的作用. */ #define INITSIZE 100 //储存空间的初始分配量 typedef int El ...

  10. 分布式远程获取配置文件config属性(修正)

    1.采用springcloud 获取github上config配置文件属性需要注意的问题; 2.此时github下面的配置文件,命名要特别注意,否则会获取不到配置里面的属性而报错,报错是因为配置文件命 ...