探秘C-signal信号

原创 2015年11月20日 10:01:31

探秘C程序中的信号

简单的不多说,也就不进行简单的介绍了。

可移植性:

首先对于<signal.h>中声明的函数不能完全的安全的定义一种可移植的用法,原则上,可以为一个只有raise报告的信号指定一个处理程序,但是很难想象它的那些方面比<setjmp.h>中的跳转函数做得更好,同时也不能保证一个指定的信号在C语言的所有实现中不可能报告,所以不管什么时候程序处理信号,它的可移植性都会受到限制。

C标准库关于信号的一些内容:

在头文件<signal.h>为处理各种各样的信号声明了一个类型和两个函数,并定义了几个宏。

定义类型:

sig_atomic_t  :这个类型的对象可以作为一个原子实体被访问,即使有异步中断发生的时候也是如此。

定义的宏:

SIG_DFL

SIG_ERR

SIG_IGN

这个三个宏展开为具有不同值的常量表达式,且他们的值和所有声明的函数的地址都不相等,下面还有几个宏,都展开为正的数值常数表达式,他们主要针对具体的情况对应的信号。

SIGABRT    异常终止,例如调用了abort()函数

SIGFPE       错误的算术操作,除0或溢出,现在广泛的所有的溢出都报告这个信号

SIGILL        一条无效的函数影像

SIGINT        收到一个交互的提示信号,异步可中断原子操作,若未保存上下文,无法恢复执行

SIGSEGV     对存储器的无效访问,段越界,就是段错误的信号

SIGTERM     送到程序中的终止请求

 

定义的函数

#include <signal.h>

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);        /*信号处理函数*/

int raise(int sig);                                        /*信号发送函数*/

<signal.h>的实现

这里我们依然是为了探秘原理,做一个简单的小例子。

首先说一下硬件信号吧。

硬件信号和我们其他一些软件信号是不同的,在某些系统中,有些代码需要得到控制权,由于这是异步的所以会选择将这些代码添加进signal 中。所以硬件系统或者计算机本身报告的信号,所以这里一定要小心。很多系统都会把控制权转移到指定的地址,但不会遵守C函数调用和返回的规则,所以处理这些每一个信号都必须使用一些汇编代码。

来硬性的告诉操作系统,这些代码需要得到控制权,此时会从这些静态的代码中获取权限。然后执行。

我们这里的着眼点主要聚焦于软件层面上。

[c]

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<signal.h>
#include<string.h>
#include<stdlib.h>

typedef int sig_atomic_t ;
typedef void _sigfun(int);

_sigfun *_sigtable[_NSIG] = {0};

int (raise)(int sig){
_sigfun *s;
if(sig <= 0 || _NSIG <= sig)
return (-1);
if((s = _sigtable[sig]) != SIG_IGN && s != SIG_DFL)
{
_sigtable[sig] = SIG_DFL;
(*s)(sig);
}else if(s == SIG_DFL){
char ac[10],*p;
switch(sig){
case SIGABRT:
p = "abort";
break;
case SIGFPE:
p = "arithmetic error";
break;
case SIGILL:
p = "invaild executable code";
break;
case SIGSEGV:
p = "termination request";
break;
default :
*(p = &ac[(sizeof ac)-1]) = '\0';
do{
*--p = sig %10 + '0';

}while((sig /= 10) != 0);
fputs("signal #",stderr);
}
fputs(p,stderr);
fputs("----terminating \n",stderr);
exit(EXIT_FAILURE);
}
return 0;
}

_sigfun * (signal)(int sig,_sigfun *fun)
{
_sigfun *s;
if(sig <= 0 || _NSIG <= sig || fun == SIG_ERR)
return (SIG_ERR);
s = _sigtable[sig];
_sigtable[sig] = fun;
fun(sig);
return (s);
}

void signalfun(int sig){
printf("I get the signal and take it\n");
return ;
}
int main(){
signal(SIGINT,signalfun);
kill(getpid(),SIGINT);

}

[/c]

查看原文:http://zmrlinux.com/2015/11/20/%e6%8e%a2%e7%a7%98c-signal%e4%bf%a1%e5%8f%b7/

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Linux下利用signal函数处理ctrl+c等信号

前言     linux下可以通过信号机制来实现程序的软中断,是一个非常有用的编程方法。我们平时在程序运行的时候按下ctrl-c、ctrl-z或者kill一个进程的时候其实都等效于向这个进程发送...

[C/C++标准库]_[初级]_[signal信号浅析]

场景: 1.在程序异常退出时,比如需要关闭外部程序或资源。 2.结构化异常不在这里的讨论范围. #include #include #include #include #include ...

Linux下c编程系统函数调用Signal信号的介绍

信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念、Linux对信号机制的大致实现方法、如何使用信号,以及有关信号的几个系统调用。 信号机制是进程之间相互传递消息的一种方法,...

《代码揭秘-从C/C++的角度探秘计算机系统》读书笔记 之第二章

第2章     揭开数据表示的面纱         计算机可以用来办公、娱乐、上网、辅助教学。但是归根结底做的事情只有一件,那就是计算。         对于一个X进制的系统中,其第n位数字的权值...

c探秘:68讲贯通C

  • 2013年03月13日 09:57
  • 48.72MB
  • 下载

大型B2C网站高性能可伸缩架构技术探秘

大型B2C网站高性能可伸缩架构技术探秘 在《世界最大的PHP站点 Facebook后台技术探秘》一文中介绍了一个大型SNS网站的技术组成。今天我们继续大型...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:探秘C-signal信号
举报原因:
原因补充:

(最多只允许输入30个字)