这些天在根据游戏后台的崩溃信息对有游戏进行调试,刚开始调试的时候方向还不是很明确,多调试几次后也摸索出来了一些规律,这里简单地对网上的一些资料做个总结,后面也会持续更新。
SIGBUS和SIGSEGV也许是我们在平时遇到的次数最多的两个 内存错误 信号。
一、SIGSEGV
Official Description:
SIGSEGV --- Segment Fault. The possible case of your encountering this error are:
1.buffer overflow --- usually caused by a pointer reference out of range.
2.stack overflow --- please keep in mind that the default stack size is 8192K.
3.illegal file access --- file operations are forbidden on our judge system.
SIGSEGV(Segment fault):指针对应的地址是无效地址,没有物理内存对应该地址。
二、SIGBUS
SIGBUS(Bus error):指针对应的地址是有效地址,但总线不能正常使用该指针。通常是未对齐的数据访问导致的。
SIGBUS的缺省行为是终止当前进程并产生core dump。
可能导致的原因:
(1)硬件故障;
(2)Linux平台执行malloc(),如果没有足够的RAM,Linux不是让malloc()失败返回,而是向当前进程分发SIGBUS信号;
(3)某些架构上访问数据时有对齐的要求,比如只能从4字节边界上读取一个4字节的数据类型。IA-32架构没有硬性对齐要求,尽管未对齐的访问降低执行效率。另外一些架构,比如SPARC、m68k,要求对齐访问,否则向当前进程分发SIGBUG信号。
测试表明,在x86/Linux、x86/Solaris、SPARC/Solaris平台上,越过栈底的地址访
问导致SIGSEGV信号。在x86/FreeBSD、x86/NetBSD、x86/OpenBSD平台上,越过栈底
的地址访问导致SIGBUS信号,而不是SIGSEGV信号。
三、SIGILL
SIGILL 信号是cpu在发现非法指令之后发出一个异常,然后由负责处理该异常的内核的ISR对含有这个非法指令的进程发出的。程序收到这个信号,一般就是报 告 illegal instruction 错误信息。
可能导致的原因:
(1)版本不一致, 比如依赖的共享库接口变了,但你仍在使用老版本的库,问题的现象通常是诡异,而且你觉得不可能挂的地方,而通常是挂在你对依赖库的调用之处。简单点说就是头文件更新了,但库文件还没有更新。
--------------------------------------------------------------------------
使用映射可能涉及到如下信号
SIGSEGV
试图对只读映射区域进行写操作
SIGBUS
试图访问一块无文件内容对应的内存区域,比如超过文件尾的内存区域,或者以
前有文件内容对应,现在为另一进程截断过的内存区域。
--------------------------------------------------------------------------
SIGBUS和SIGSEGV也许是我们在平时遇到的次数最多的两个 内存错误 信号。
一、SIGSEGV
Official Description:
SIGSEGV --- Segment Fault. The possible case of your encountering this error are:
1.buffer overflow --- usually caused by a pointer reference out of range.
2.stack overflow --- please keep in mind that the default stack size is 8192K.
3.illegal file access --- file operations are forbidden on our judge system.
SIGSEGV(Segment fault):指针对应的地址是无效地址,没有物理内存对应该地址。
二、SIGBUS
SIGBUS(Bus error):指针对应的地址是有效地址,但总线不能正常使用该指针。通常是未对齐的数据访问导致的。
SIGBUS的缺省行为是终止当前进程并产生core dump。
可能导致的原因:
(1)硬件故障;
(2)Linux平台执行malloc(),如果没有足够的RAM,Linux不是让malloc()失败返回,而是向当前进程分发SIGBUS信号;
(3)某些架构上访问数据时有对齐的要求,比如只能从4字节边界上读取一个4字节的数据类型。IA-32架构没有硬性对齐要求,尽管未对齐的访问降低执行效率。另外一些架构,比如SPARC、m68k,要求对齐访问,否则向当前进程分发SIGBUG信号。
测试表明,在x86/Linux、x86/Solaris、SPARC/Solaris平台上,越过栈底的地址访
问导致SIGSEGV信号。在x86/FreeBSD、x86/NetBSD、x86/OpenBSD平台上,越过栈底
的地址访问导致SIGBUS信号,而不是SIGSEGV信号。
三、SIGILL
SIGILL 信号是cpu在发现非法指令之后发出一个异常,然后由负责处理该异常的内核的ISR对含有这个非法指令的进程发出的。程序收到这个信号,一般就是报 告 illegal instruction 错误信息。
可能导致的原因:
(1)版本不一致, 比如依赖的共享库接口变了,但你仍在使用老版本的库,问题的现象通常是诡异,而且你觉得不可能挂的地方,而通常是挂在你对依赖库的调用之处。简单点说就是头文件更新了,但库文件还没有更新。
--------------------------------------------------------------------------
使用映射可能涉及到如下信号
SIGSEGV
试图对只读映射区域进行写操作
SIGBUS
试图访问一块无文件内容对应的内存区域,比如超过文件尾的内存区域,或者以
前有文件内容对应,现在为另一进程截断过的内存区域。
--------------------------------------------------------------------------
Signal | Description |
SIGABRT | 由调用abort函数产生,进程非正常退出 |
SIGALRM | 用alarm函数设置的timer超时或setitimer函数设置的interval timer超时 |
SIGBUS | 某种特定的硬件异常,通常由内存访问引起 |
SIGCANCEL | 由Solaris Thread Library内部使用,通常不会使用 |
SIGCHLD | 进程Terminate或Stop的时候,SIGCHLD会发送给它的父进程。缺省情况下该Signal会被忽略 |
SIGCONT | 当被stop的进程恢复运行的时候,自动发送 |
SIGEMT | 和实现相关的硬件异常 |
SIGFPE | 数学相关的异常,如被0除,浮点溢出,等等 |
SIGFREEZE | Solaris专用,Hiberate或者Suspended时候发送 |
SIGHUP | 发送给具有Terminal的Controlling Process,当terminal被disconnect时候发送 |
SIGILL | 非法指令异常 |
SIGINFO | BSD signal。由Status Key产生,通常是CTRL+T。发送给所有Foreground Group的进程 |
SIGINT | 由Interrupt Key产生,通常是CTRL+C或者DELETE。发送给所有ForeGround Group的进程 |
SIGIO | 异步IO事件 |
SIGIOT | 实现相关的硬件异常,一般对应SIGABRT |
SIGKILL | 无法处理和忽略。中止某个进程 |
SIGLWP | 由Solaris Thread Libray内部使用 |
SIGPIPE | 在reader中止之后写Pipe的时候发送 |
SIGPOLL | 当某个事件发送给Pollable Device的时候发送 |
SIGPROF | Setitimer指定的Profiling Interval Timer所产生 |
SIGPWR | 和系统相关。和UPS相关。 |
SIGQUIT | 输入Quit Key的时候(CTRL+\)发送给所有Foreground Group的进程 |
SIGSEGV | 非法内存访问 |
SIGSTKFLT | Linux专用,数学协处理器的栈异常 |
SIGSTOP | 中止进程。无法处理和忽略。 |
SIGSYS | 非法系统调用 |
SIGTERM | 请求中止进程,kill命令缺省发送 |
SIGTHAW | Solaris专用,从Suspend恢复时候发送 |
SIGTRAP | 实现相关的硬件异常。一般是调试异常 |
SIGTSTP | Suspend Key,一般是Ctrl+Z。发送给所有Foreground Group的进程 |
SIGTTIN | 当Background Group的进程尝试读取Terminal的时候发送 |
SIGTTOU | 当Background Group的进程尝试写Terminal的时候发送 |
SIGURG | 当out-of-band data接收的时候可能发送 |
SIGUSR1 | 用户自定义signal 1 |
SIGUSR2 | 用户自定义signal 2 |
SIGVTALRM | setitimer函数设置的Virtual Interval Timer超时的时候 |
SIGWAITING | Solaris Thread Library内部实现专用 |
SIGWINCH | 当Terminal的窗口大小改变的时候,发送给Foreground Group的所有进程 |
SIGXCPU | 当CPU时间限制超时的时候 |
SIGXFSZ | 进程超过文件大小限制 |
SIGXRES | Solaris专用,进程超过资源限制的时候发送 |