Linux signal&coredump



Linux signal&coredump

 

当进程发生崩溃时,kernel会以信号的方式通知进程,每个信号伴随着动作,比如产生coredump,或终止程序。

ptrace用于跟踪调试进程的,通过ptrace可以获得目标进程的CPU寄存器,进程空间的任何内存内容。

  1. Signal

     

    通过命令kill -l可以查询所有的信号

     

    信号值及对应的处理动作:

     

    SIGHUP 1 终端挂起或者控制进程终止

     

    SIGINT 2 键盘中断(如break键被按下)

     

    SIGQUIT 3  键盘的退出键被按下

     

    SIGILL 4  非法指令

     

5) SIGTRAP
由断点指令或其它trap指令产生. 由debugger使用。

 

SIGABRT 6  abort(3)发出的退出指令

 

7) SIGBUS
非法地址, 包括内存地址对齐(alignment)出错。

 

SIGFPE 8 浮点异常

 

SIGKILL  AEF Kill信号

 

SIGSEGV 11  无效的内存引用segment fault 是内存访问错误/段错误

 

Signale 11:由应用引起的segment fault, 是轻量级的,因为当非法读时, 或者非法写时系统都及时给了提示,找到代码行修改错误即可。当出现内存访问错误时,较好的情况: 此时函数调用栈没有遭到破坏,此时系统可以直接给出是什么位置引起异常。较糟的情况: 堆栈段已经被破坏(非法驱动引起死机,重启等),系统仅能给出最底层或根本给不出引起异常的准确位置。 虽然这种情况更难下手,但可以断定是不久前有人非法清理或覆盖了堆栈内存。

 

#####堆栈内存的区别######

栈内存 :创建一个方法的时候,会将一些局部变量放在栈内存中;随着方法的结束而被销毁;

堆内存 :创建一个对象的时候(创建对象的成本比较大,一般都会放在运行时数据区,便于反复利用。)它不会随着方法的结束而被销毁,因为这时可能存在其他的变量对它进行引用,除非没有其他引用变量引用时,系统的回收垃圾机制会在合适的时刻回收它。

 

SIGPIPE 13 管道破裂: 写一个没有读端口的管道

 

SIGALRM 14 alarm(2)发出的信号

 

SIGTERM 15  终止信号

 

SIGUSR1 30,10,16  用户自定义信号1

 

SIGUSR2 31,12,17  用户自定义信号2

 

SIGCHLD 20,17,18  子进程结束信号

 

SIGCONT 19,18,25  进程继续(曾被停止的进程)

 

SIGSTOP 17,19,23   终止进程

 

SIGTSTP 18,20,24  控制终端(tty)上按下停止键

 

SIGTTIN 21,21,26  后台进程企图从控制终端读

 

SIGTTOU 22,22,27   后台进程企图从控制终端写

 

  1. core dump

    coredump是分析NE的材料,也是最完整的材料,除了能从调用栈直接看出问题外,基本上NE调试都需要coredump

    当程序挂掉的时候,操作系统就会把程序挂掉时的内存内容写入一个叫做core的文件里,以便于调试。这个过程,因此叫做core dump

    Note:目的是找到程序出错的地方!程序崩溃了不一定都产生 core文件

    通常情况下,core文件会包含了程序运行时的内存,寄存器状态,堆栈指针,内存管理信息还有各种函数调用堆栈信息等。

     

    ##coredump产生的几种可能情况##

  • 内存访问越界

     a) 使用错误的下标,导致数组访问越界。

     b) 搜索字符串时,依靠字符串结束符来判断字符串是否结束,但是字符串没有正常的使用结束符。

     c) 使用strcpy, strcat, sprintf, strcmp,strcasecmp等字符串操作函数,将目标字符串读/写爆。应该使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函数防止读写越界。

  • 多线程程序使用了线程不安全的函数。

  •  多线程读写的数据未加锁保护。

  • 对于会被多个线程同时访问的全局数据,应该注意加锁保护,否则很容易造成coredumpsynchronized

  •  非法指针

     a) 使用空指针

     b) 随意使用指针转换。一个指向一段内存的指针,除非确定这段内存原先就分配为某种结构或类型,或者这种结构或类型的数组,否则不要将它转换为这种结构或类型的指针,而应该将这段内存拷贝到一个这种结构或类型中,再访问这个结构或类型。这是因为如果这段内存的开始地址不是按照这种结构或类型对齐的,那么访问它时就很容易因为bus errorcore dump

  •  堆栈溢出

  • 不要使用大的局部变量(因为局部变量都分配在栈上),这样容易造成堆栈溢出,破坏系统的栈和堆结构,导致出现莫名其妙的错误。   

     

    进入c300目录下:

    android@ubuntu:~/A/c300$ cat  /proc/sys/kernel/core_pattern

    |/usr/share/apport/apport %p %s %c %P

                进程ID、导致core的信号、

    # Core_pattern的格式#

    可以在core_pattern模板中使用的变量:

    %% 单个%字符

    %p dump进程的进程ID

    %u dump进程的实际用户ID

    %g dump进程的实际组ID

    %s 导致本次core dump的信号

    %t core dump的时间

    %h 主机名

    %e 程序文件名

猜你喜欢

转载自blog.csdn.net/Toc_SunWinner/article/details/79314715