Linux高级调试与优化——信号量机制与应用程序崩溃
背景介绍
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高级调试与优化——信号量机制与应用程序崩溃的更多相关文章
- Linux高级调试与优化——gdb调试命令
番外 2019年7月26日至27日,公司邀请<软件调试>和<格蠹汇编——软件调试案例集锦>两本书的作者张银奎老师进行<Linux高级调试与优化>培训,有幸聆听张老师 ...
- Linux高级调试与优化——内存泄漏实战分析
最近在整理Linux调试方面的文档,正好碰到了一个内存泄漏踩栈的问题,借此机会记录一下分析过程. 首先,发现问题之后,赶紧看一下产生coredump文件没有,果不其然,产生了coredump,果断上g ...
- Linux高级调试与优化——ptrace
ptrace (process trace) #include <sys/ptrace.h> long ptrace(enum __ptrace_request request, pid_ ...
- Linux高级调试与优化——内存管理
1.物理地址和虚拟地址 Linux采用页表机制管理内存,32位系统中页大小一般为4KB,物理内存被划分为连续的页,每一个页都有一个唯一的页号. 为了程序的的可移植性,进程往往需要运行在flat mem ...
- Linux高级调试与优化——用户态堆
内存问题是软件世界的住房问题 嵌入式Linux系统中,物理内存资源通常比较紧张,而不同的进程可能不停地分配和释放不同大小的内存,因此需要一套高效的内存管理机制. 内存管理可以分为三个层次,自底向上分别 ...
- Linux高级调试与优化——同时抓取coredump和maps文件
Linux内核源码 Documentation/sysctl/kernel.txt core_pattern: core_pattern: core_pattern is used to specif ...
- Linux高级调试与优化——进程管理和调度
进程管理 进程和文件是Linux操作系统的两个最基本的抽象. 进程是处于执行期的程序,进程不仅仅局限于一段可执行程序代码,通常还包含其他资源,如打开的文件.挂起的信号.内核内部数据.处理器状态.进程地 ...
- Linux高级调试与优化——Address Sanitizer
Address Sanitizer ASAN最早可以追溯到 LLVM 的 sanitizers项目(https://github.com/google/sanitizers),这个项目包含了Addre ...
- 09、高级编程之基于排序机制的wordcount程序
package sparkcore.java; import java.util.Arrays; import java.util.Iterator; import org.apache.spark. ...
随机推荐
- 编写优秀 CSS 代码的 8 个策略
编写基本的CSS和HTML是我们作为Web开发人员学习的首要事情之一.然而,我遇到的很多应用程序显然没有人花时间真正考虑前端开发的长久性和可维护性. 我认为这主要是因为许多开发人员对组织CSS / H ...
- python3:tuple元组
https://www.runoob.com/python3/python3-tuple.html 元组使用小括号,列表使用方括号. 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可. Py ...
- 1-Kubernetes基本概念
Kubernetes中的大部分概念如Node.Pod.Replication Controller.Service等都可以看作一种"资源对象",几乎所有的资源对象都可以通过Kube ...
- phpmyadmin导入大容量.sql文件
phpmyadmin导入大容量.sql文件 在phpmyadmin目录文件夹下建立一个文件夹,如importSqlFile 将想要导入的sql文件放入importSqlFile文件夹中 打开confi ...
- ifconfig命令返回找不到“-bash: ifconfig: command not found”
“-bash: ifconfig: command not found“因为系统没有安装net-tools yum -y install net-tools
- python_实现选课系统
校园管理系统 角色: 学校.学员.课程.讲师 要求: 1. 创建北京.上海 2 所学校 2. 创建linux , python , go 3个课程 , linux\py 在北京开, go 在上海开 3 ...
- java数据结构复习02
1.递归问题 1.1汉诺塔问题(递归) 问题描述三个柱子,起初有若干个按大小关系顺序安放的盘子,需要全部移动到另外一个柱子上.移动规则:在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘.移动 ...
- TDD之断言验证System.out.print输出
业务类: public class OutDemo { public void print(String content) { System.out.print(content); } } 测试类: ...
- vue和cordova项目整合打包,并实现vue调用android的相机的demo
经过网上查找很多资料,发现很多只有vue+cordova的项目整合,但是vue使用cordova插件的文章很少,现在把从创建cordova和创建vue到vue使用插件到项目打包到android手机运行 ...
- SQL语句 函数
6.4 Functions 6.4.1 Numeric abs/mod 绝对值/求模 sqrt/power/exp 求幂 ceil/floor/round 取整 trunc 截取小数点 sin/c ...