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

我们在写代码时,有时会有内存非法使用,这种问题一般比较难定位。但是如果有信号处理函数,就可以在捕捉到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

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

Linux 信号的更多相关文章

  1. Linux信号类型说明

    说明 在Linux系统开发中经常要使用到信号来实现异步通知机制.而在Linux系统中信号有很多种,也不用全部记住,学习几种常见的信号,学会使用即可:当然也要知道用哪种方式能够发送这样的信号. 查看li ...

  2. Linux信号基础

    Linux信号基础   作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Linux进程基础一文中已经提到,Linux以进程为单位来 ...

  3. Linux信号(signal) 机制分析

    Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...

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

    在实际开发过程中,大家可能会遇到段错误的问题,虽然是个老问题,但是其带来的隐患是极大的,只要出现一次,程序立即崩溃中止.如果程序运行在PC中,segment fault的调试相对比较方便,因为可以通过 ...

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

    信号分类 不可靠信号 Linux信号机制基本上是从UNIX系统中继承过来的.早期UNIX系统中的信号机制比较简单和原始,后来在实践中暴露出一些问题,它的主要问题是: 1.进程每次处理信号后,就将对信号 ...

  6. 非常好的一篇对linux信号(signal)的解析 (转载)【转】

    转自:https://blog.csdn.net/return_cc/article/details/78845346 Linux信号(signal) 机制分析 转载至:https://www.cnb ...

  7. Linux 信号:signal 与 sigaction

    0.Linux下查看支持的信号列表: france@Ubuntux64:~$ kill -l ) SIGHUP ) SIGINT ) SIGQUIT ) SIGILL ) SIGTRAP ) SIGA ...

  8. Linux信号机制

    Linux信号(signal) 机制分析 [摘要]本文分析了Linux内核对于信号的实现机制和应用层的相关处理.首先介绍了软中断信号的本质及信号的两种不同分类方法尤其是不可靠信号的原理.接着分析了内核 ...

  9. python学习笔记——多进程间通信——Linux信号基础

    1 信号的基本描述 Signal信号(其全程为软中断信号)是Linux系统编程中非常重要的概念,信号是异步进程中通信的一种方式. 作用是通知进程发生了异步事件.进程之间可以调用系统来传递信号, 本身内 ...

  10. linux信号Linux下Signal信号太详细了,终于找到了

    linux信号Linux下Signal信号太详细了,终于找到了 http://www.cppblog.com/sleepwom/archive/2010/12/27/137564.html

随机推荐

  1. HDU 1512 Monkey King

    左偏树.我是ziliuziliu,我是最强的 #include<iostream> #include<cstdio> #include<cstring> #incl ...

  2. 【英语】Bingo口语笔记(42) - Got系列

  3. AsyncTask类

    1.定义         异步任务类,在类中实现异步操作,并提供回调方法反馈当前异步执行的程度,最后反馈 的结果提供给UI主线程.         <1>Android线程         ...

  4. 使用C#代码发起K2 Blackpearl流程

    转:http://www.cnblogs.com/dannyli/archive/2011/08/02/2125285.html 使用C#代码,发起一个K2的流程,其形式和链接SQL Server数据 ...

  5. 为什么Jquery对input file控件的onchange事件只生效一次

    今天在做jquery对input file控件的onchange事件进行监听,就一直只生效一次,不知道Jquery为什么对file控件没有做到每次改变触发onchange事件的效果,但是还是有好几种解 ...

  6. 关于浮动-float

    1.存在浏览器兼容问题:js代码 2.对于这种存在浏览器兼容问题的问题,我们可以绕开兼容性问题,先在css样式写好,然后通过该变className 3.学习的博客 https://paran.io/c ...

  7. RedHat 5 配置CentOS yum 更新源

    YUM是Redhat Linux在线安装更新及软件的工具,但是这是RHEL5的收费功能,如果没有购买Redhat的服务时不能使用RHEL5的更新源的,会提示注册. 由于CentOS是从Redhat演化 ...

  8. ORA-12516: TNS: 监听程序无法找到匹配协议栈的可用句柄解决方法

    1.查看当前连接进程数SQL>select count(*) from v$process;2.查看连接数上限SQL>select value from v$parameter where ...

  9. GC算法 垃圾收集器

    GC算法 垃圾收集器 参考:http://www.cnblogs.com/ityouknow/p/5614961.html 概述 垃圾收集 Garbage Collection 通常被称为“GC”,它 ...

  10. Linux 的 screen用法

    screen可以将任务挂起,即将任务放在后台,一般5个任务左右. 1.新建screen会话:直接输入screen命令或者screen -S [会话名称] 2.退出会话:按下组合键Ctrl+a并松开,此 ...