Linux 信号

每个进程都需要有个信号处理函数,以捕捉异常信号。

我们在写代码时,有时会有内存非法使用,这种问题一般比较难定位。但是如果有信号处理函数,就可以在捕捉到SEGV信号后打印出详细信息以定位问题。

下面写一个简单的例子,来定位非法内存访问。

#include <stdio.h>
#define __USE_GNU
#include <ucontext.h>
#include <sys/prctl.h>
#include <execinfo.h>
#include <stdlib.h>
#include <sys/types.h>
#include <errno.h>
static void show_maps()
{
  char cmd[128];
  snprintf(cmd, sizeof(cmd), "cat /proc/%d/maps", getpid());
  system(cmd);
}

static void show_backtrace()
{
  void *trace[32];
  int trace_size;
  char **messages;
  trace_size = backtrace(trace ,32);
  int idx;
  messages = backtrace_symbols(trace, trace_size);
  if (NULL != messages)
  {
    for (idx = 0; idx < trace_size; idx++)
    {
      printf("%s\n", messages[idx]);
    }
    free(messages);
  }
}
static void show_regs(mcontext_t *regs)
{
  char comm[20] = {‘\0‘};
  prctl(PR_GET_NAME, comm);
  printf("PID:%d,comm:%20s\n", getpid(), comm);
  printf("EIP:%p\n",(void*) regs->gregs[REG_EIP]);
}
static void sighandler(int signo, siginfo_t *info, void *context)
{
  ucontext_t *uc = (ucontext_t *)context;
  switch (signo)
  {
    case SIGSEGV :
    printf("Invalid mem!!! Fault addr:%p\n",(void*)( info->si_addr));
    show_regs(&(uc->uc_mcontext));
    show_backtrace();
    show_maps();
    exit(0);
    break;
    default:
    break;
  }
}
int register_signalHandler()
{
  struct sigaction sa;
  int ret;
  sa.sa_sigaction = &sighandler;
  sigemptyset(&sa.sa_mask);
  sa.sa_flags = SA_SIGINFO;
  if (0 != sigaction(SIGSEGV, &sa, NULL))
  {  
    printf("sigaction fail, errno:%d\n", errno);
    return ret;
  }
  return 0;
}
void func()
{

  printf("func!\n");
  int *p;
  *p = 8;
}

int main(void)
{
  register_signalHandler();
  func();
  return 0;
}

在func函数中有个非法内存使用。

gcc -g signal.c -o signal

运行signal进程:

EIP寄存器地址在地址区间08048000~08049000是在进程的.text段。

我们可以通过addr2line进行定位:

76行正好是*p=8那一行。

如果SEGEV不是发生在进程的代码段,发生在某个so内。假如发生在0x7553654,而且so load到进程中的0xb7553000,那么addr2line应该查看地址0x654;

也可以在gdb中查看list *0x8048951

也可以反编译可执行文件,来查看地址。

时间: 2024-10-07 05:28:22

Linux 信号的相关文章

Linux 信号signal处理机制(ZZ)

http://www.cnblogs.com/taobataoma/archive/2007/08/30/875743.html 信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念.Linux对信号机制的大致实现方法.如何使用信号,以及有关信号的几个系统调用. 信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断.从它的命名可以看出,它的实质和使用很象中断.所以,信号可以说是进程控制的一部分. 一.信号的基本概念 本节先介绍信号的一些基本概念,然后

LINUX 信号概念详解

LINUX 信号概念详解 我们运行如下命令,可看到Linux支持的信号列表: # kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP

Linux信号列表

我们运行如下命令,可看到Linux支持的信号列表:~$ kill -l1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR213) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) S

Linux信号(signal) 机制分析

[摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核对于信号的处理流程包括信号的触发/注册/执行及注销等.最后介绍了应用层的相关处理,主要包括信号处理函数的安装.信号的发送.屏蔽阻塞等,最后给了几个简单的应用实例. [关键字]软中断信号,signal,sigaction,kill,sigqueue,settimer,sigmask,sigprocmask,sigset_t 1       信

Linux信号详解

Linux信号详解 一 信号的种类 可靠信号与不可靠信号, 实时信号与非实时信号 可靠信号就是实时信号, 那些从UNIX系统继承过来的信号都是非可靠信号, 表现在信号 不支持排队,信号可能会丢失, 比如发送多次相同的信号, 进程只能收到一次. 信号值小于 SIGRTMIN的都是非可靠信号. 非可靠信号就是非实时信号, 后来, Linux改进了信号机制, 增加了32种新的信号, 这些信 号都是可靠信号, 表现在信号支持排队, 不会丢失, 发多少次, 就可以收到多少次. 信号值 位于 [SIGRTM

Linux 信号signal处理机制

信号是Linux编程中非常重要的部分,本文将详细介绍信号机制的基本概念.Linux对信号机制的大致实现方法.如何使用信号,以及有关信号的几个系统调用. 信号机制是进程之间相互传递消息的一种方法,信号全称为软中断信号,也有人称作软中断.从它的命名可以看出,它的实质和使用很象中断.所以,信号可以说是进程控制的一部分. 一.信号的基本概念 本节先介绍信号的一些基本概念,然后给出一些基本的信号类型和信号对应的事件.基本概念对于理解和使用信号,对于理解信号机制都特别重要.下面就来看看什么是信号. 1.基本

Linux 信号理解(二)

linux下信号基本概念见:Linux 信号理解(一) 接下来讲重点讲述信号捕捉设定 #include<stdio.h> #include<signal.h> #include<errno.h> void capture_sig(int num) { int n=4; printf("capture_sig is called \n"); while(n--) { sleep(1); printf(" num:%d \n",num

Linux信号实践(2) --信号分类

信号分类 不可靠信号 Linux信号机制基本上是从UNIX系统中继承过来的.早期UNIX系统中的信号机制比较简单和原始,后来在实践中暴露出一些问题,它的主要问题是: 1.进程每次处理信号后,就将对信号的响应设置为默认动作.在某些情况下,将导致对信号的错误处理:因此,用户如果不希望这样的操作,那么就要在信号处理函数结尾再一次调用signal(),重新安装该信号. 2.因此导致, 早期UNIX下的不可靠信号主要指的是进程可能对信号做出错误的反应以及信号可能丢失. Linux支持不可靠信号,但是对不可

linux信号-------初涉

一.信号的本质 软中断信号(signal,又简称为信号)用来通知进程发生了异步事件.在软件层次上是对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的.信号是进程间通信机制中唯一的异步通信机制,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达.进程之间可以互相通过系统调用kill发送软中断信号.内核也可以因为内部事件而给进程发送信号,通知进程发生了某个事件.信号机制除了基本通知功能外,还可以传递附加信息 二.信号的分类 1)

利用linux信号机制调试段错误(Segment fault)

在实际开发过程中,大家可能会遇到段错误的问题,虽然是个老问题,但是其带来的隐患是极大的,只要出现一次,程序立即崩溃中止.如果程序运行在PC中,segment fault的调试相对比较方便,因为可以通过串口.显示器可以查看消息,只要程序运行,通过GDB调试工具即可捕捉产生segment fault的具体原因.但是不知大家有没有想法,当程序运行在嵌入式设备上时,你所面临资源的缺乏,你没有串口打印信息,没有显示器可查看,你不知道程序运行的状态,如果程序的产生segment falut这种bug发生的周