sigaction

Linux下捕捉信号

梦想的初衷 提交于 2020-03-31 00:37:39
关于 信号signal的知识铺垫 点这里 信号由三种处理方式: 忽略 执行该信号的默认处理动作 捕捉信号 如果信号的处理动作是用户自定义函数,在信号递达时就调用这个自定义函数,这称为 捕捉信号 。 进程收到一个信号后不会被立即处理,而是在恰当时机进行处理!即 内核态返回用户态之前 ! 但是由于信号处理函数的代码在用户空间,所以这增加了内核处理信号捕捉的复杂度。 内核实现信号捕捉的步骤: 用户为某信号注册一个信号处理函数sighandler。 当前正在执行主程序,这时候因为中断、异常或系统调用进入内核态。 在处理完异常要返回用户态的主程序之前,检查到有信号未处理,并发现该信号需要按照用户自定义的函数来处理。 内核决定返回用户态执行sighandler函数,而不是恢复main函数的上下文继续执行!(sighandler和main函数使用的是不同的堆栈空间,它们之间不存在调用和被调用的关系,是两个独立的控制流程) sighandler函数返回后,执行特殊的系统调用sigreturn从用户态回到内核态 检查是否还有其它信号需要递达,如果没有 则返回用户态并恢复主程序的上下文信息继续执行。 signal 给某一个进程的某一个信号(标号为signum)注册一个相应的处理函数,即对该信号的默认处理动作进行修改,修改为handler函数指向的方式; #include <signal.h>

信号之sigaction函数

杀马特。学长 韩版系。学妹 提交于 2020-03-22 09:42:06
可靠机制,不会恢复默认信号处理程序: 新的信号安装函数sigaction :sigaction函数用于改变进程收到的特定信号后的行为   int sigaction(int signum,const struct sigaction *act,const struct sigaction *old); //成功返回0,失败返回-1   struct sigaction{     void (*sa_handler)(int);     sigset_t sa_mask;//屏蔽集合     int sa_flags;     //可选     void (*sa_sigaction) (int,siginfo_t*,void*) //与void (*sa_handler)(int)任选其一,这个针对可靠信号   } 1、第一个参数为信号的值,可以为除SIGKILL以及SIGSTOP外的任何一个特定有效的信号; 2、第二个参数是一个指向结构sigaction的一个实例的指针,在结构sigaction的实例中,指定了对特定 信号的处理,可以为空,进程会以缺省的方式对信号处理;这个结构体包含了对指定信号的处理,信号传导的信息,信号处理函数执行过程中应屏蔽掉哪些函数。 3、第三个参数oldact指向的对象用来保存原来对应信号的处理函数,可以指定oldact为NULL #include

sigaction()

点点圈 提交于 2020-03-19 20:43:05
NAME     sigaction - examine and change a signal action SYNOPSIS     #include <signal.h>     int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); DESCRIPTION     The sigaction() system call is used to change the action taken by a process on receipt of a specific signal.      signum specifies the signal and can be any valid signal except SIGKILL and SIGSTOP.     If act is non-null, the new action for signal signum is installed from act. If oldact is non-null, the previous action is saved in oldact.     The sigaction structure is defined as something like      

[学习笔记]信号的高级用法

↘锁芯ラ 提交于 2020-03-15 13:45:33
sigaction函数注册信号处理函数 sigaction 函数 q 包含头文件<signal.h> q 功能:sigaction函数用于改变进程接收到特定信号后的行为。 q 原型: int sigaction(int signum,const struct sigaction *act,const struct sigaction *old); q 参数 q 该函数的第一个参数为信号的值,可以为除SIGKILL及SIGSTOP外的任何一 个特定有效的信号(为这两个信号定义自己的处理函数,将导致信号安装错误) q 第二个参数是指向结构sigaction的一个实例的指针,在结构 sigaction的实例中,指定了对特定信号的处理,可以为空,进程会以缺省方式对信号处理 q 第三个参数oldact指向的对象用来保存原来对相应信号的处理,可指定oldact为NULL。 q 返回值:函数成功返回0,失败返回-1 signal(num., handle) sigaction 结构体 q 第二个参数最为重要,其中包含了对指定信号的处理、信号所传递的信息、信号处理函数执行过程中应屏蔽掉哪些函数等等 struct sigaction { void (*sa_handler)(int); //信号处理程序 不接受额外数据 void (*sa_sigaction)(int, siginfo_t *,

信号发送接收函数:sigqueue/sigaction

左心房为你撑大大i 提交于 2020-03-11 23:57:48
  信号是一种古老的进程间通信方式,下面的例子利用 sigqueue发送信号 并附带数据; sigaction函数接受信号 并且处理时接受数据。 1、 sigqueue: 新的信号发送函数,比kill()函数传递了更多附加信息 ,但它 只能向一个进程发送信号 ,针对实时信号( 支持排队不会丢失 ),与sigaction配合使用。   int sigqueue(pid_t pid, int sig, const union sigval value);   typedef union sigval   {     int sival_int;     void *sival_ptr;   }sigval_t; 其中第一个参数指接收信号的进程ID;第二个参数确定即将发送的信号;第三个参数指定了信号传递的参数(可用于进程间通信,传递附带数据)。函数成功返回0,失败返回-1。 2、sigaction函数可以用来接受信号进行信号处理 int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);   struct sigaction{     void (*sa_handler)(int);     sigset_t sa_mask;      int sa_flag;//接收数据     

iOS异常捕获和处理

余生颓废 提交于 2020-02-27 05:05:26
2013年4月份整理的代码,仅作记录: //先宏定义 //发布和未发布状态的日志切换 #ifdef DEBUG //异常栈开关 #define STACK_KEY YES //日志重定向开关 #define STDERR_KEY NO //调试日志 #define DebugLog(format,...) NSLog(@"{%s,%d}" format, __FUNCTION__,__LINE__,##__VA_ARGS__) //异常栈日志 #define StackLog(format,...) NSLog(@"{%s,%d}" format, __FUNCTION__,__LINE__,##__VA_ARGS__) //输出日至 #define DLOG(...) NSLog(__VA_ARGS__) //输出详细日志 #define DLOGEXT(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); //输出调用 #define DLOGCALL DLOG(@"[%@ %@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd)) //输出方法 #define

第十章:信号

[亡魂溺海] 提交于 2020-02-18 07:13:54
一、信号的概念 使用信号进行进程间通信(IPC)是UNIX的一种传统机制,Linux也支持这种机制。 每一个信号都有一个名字,这些名字都以SIG开头。如SIGINT表示终端中断(Ctrl + C产生),SIGQUIT表示终端退出,SIGIO表示异步I/O。 我们可以使用kill -l命令查看所有信号 信号属于异步事件,它的发生对于进程是随机的。进行必须要告诉内核当信号发生时怎么处理。 对于信号的处理,我们可以有以下几种方式: 1. 忽略此信号,但是SIGKILL和SIGSTOP不能忽略,因为这两个信号向内核提供使进程终止的方法。 2. 捕捉并处理信号。 3. 执行系统默认动作,如Ctrl + C就是终端中断,程序中不做任何信号处理。 二、signal()函数 signal()函数的使用方法: 1. 包含头文件:#include <signal.h>。 2. 定义信号处理函数:typedef void (*sighandler_t)(int signum),其中的signum是信号名。 3. 注册信号:signal(int signum, sighandler_t handler);。 示例如下: 1 #include <stdio.h> 2 #include <unistd.h> 3 #include <signal.h> 4 5 static void sig_handler

程序Crash后的调试技巧

寵の児 提交于 2020-02-17 07:42:34
当我们的程序突然死掉了,Xcode突然送出一段 "message sent to deallocated instance" 的错误,我们该怎样定位我们的程序bug呢? 又或者我们已经通过AdHoc发布了我们的β版程序,更甚至于我们的程序已经发布到了app store上;而当我们的程序突然在测试人员,或者是最终用户那里突然当掉,是否能收集到这样的日志信息,供我们解析bug呢? 下面的文章中我将逐步深入地说明这些技巧 模拟器上显示堆栈信息 当我们在模拟器上调试时,可能经常遇到下面的内存访问错误: 1 2011-01-17 20:21:11.41 App[26067:207] *** -[Testedit retain]: message sent to deallocated instance 0x12e4b0 首先,我们为了定位问题,需要Xcode帮我们显示栈信息,可以通过Scode中执行文件的属性来设置。如下图所示,选中 MallocStackLogging 选项。该选项只能在模拟器上有效,并且如果你改变了iOS的版本后也需要再次设定该选项。 这之后,你就可以在终端输入 info malloc-history 命令,如下所示; 1 (gdb) info malloc-history 0x12e4b0 之后得到如下的堆栈信息,从此分析具体的问题所在。 除此之外,也可以使用下面的命令

[Linux:]信号

送分小仙女□ 提交于 2020-02-17 05:15:31
1.如何理解信号 例如在生活中,快递员告诉我们快递到了,那么我们会终止手上的事,去取快递,这就是一种信号。 站在操作系统的角度,再来理解信号: 1.用户输入命令,在Shell下启动一个前台进程。 2. 用户按下 Ctrl-C ,这个键盘输入产生一个硬件中断,被OS获取,解释成信号,发送给目标前台进程 3. 前台进程因为收到信号,进而退出。 所以,显而易见,信号是操作系统与用户通信的一种方式,也可以是进程间通信的方式。 2. Linux下信号机制 信号是进程间时间异步通知的一种方式,属于软中断。 在Linux下我们可以使用 kill -l 命令查看系统定义的信号列表。 2.1 信号常见的处理方式 忽略此信号。 执行该信号的默认处理动作。 提供一个信号处理函数,要求内核在处理信号时切换到用户态执行这个处理函数,这种处理方式称之为捕捉一个信号。 2.2 产生信号的方式 通终端按键产生信号(如常用的Ctrl+z) 调用系统函数向进程发信号 由软件条件产生信号 硬件异常产生信号 3. Linux下信号阻塞 先来了解一些信号相关常见的概念: 信号递达(Delivery):实际执行信号的处理动作 未决信号(Pending):信号从产生到传递之间的状态。 阻塞信号(Blocking):被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作. 在内核中

Linux信号机制(二)-- 信号集

扶醉桌前 提交于 2020-01-17 15:24:18
什么是信号集? 收到一个信号之后执行信号处理函数,在执行信号处理函数的过程中如果又来了一个相同的信号,那么这个信号将会被阻塞,直到信号处理函数执行完之后,再响应被阻塞的信号,注意如果信号被阻塞期间又收到了该信号,那么多个信号的处理会被合并为1次 比如正在执行SIGUSR1的信号处理函数,此时又收到了一个SIGUSR1信号,那么该信号将会被阻塞,直到信号处理函数执行完之后,再次执行该函数。如果在阻塞期间又收到了SIGUSER1信号,接下来只再调用一次SIGUSR1的信号处理函数 信号集就是用来记录当前收到了哪个信号,会把当前信号的标志位置成“正在处理”,如果此时再收到该信号,那么信号就阻塞等待 使用数据类型sigset_t表示信号集,在Linux中该类型是一个32位无符号整数,这是因为在Linux中定义了32种信号,每一个信号用32位无符号整型变量中的一位来标志,如果该位置为1,那么表示正在处理该信号,如果置为0表示可以处理该信号。注意:有的操作系统,信号个数多于32,此时就不能用32位整数表示一个信号集了 操作信号集的函数 函数原型如下: [1] #include <signal.h> // @brief 清空信号集,全部位置0 int sigemptyset(sigset_t *set); // 全部位置1 int sigfillset(sigset_t *set); //