#include <iostream>
using namespace std
/**********************************
//project ->Properties ->C/C++ ->Code Generation -->Enable C++ Exceptions
//选择 Yes with SEH Exceptions (/EHa) 这样的话C++的try catch 也可以捕获到空指针,内存越界,0除异常
//默认是选择Yes (/EHsc)
**********************************/
void TestIntType()
{
try
{
throw 1
}
catch(...)
{
cout<<"在 try block 中, 准备抛出一个异常." <<endl
}
}
void TestDoubleType()
{
try
{
throw 0.5
}
catch(...)
{
cout<<"在 try block 中, 准备抛出一个异常." <<endl
}
}
void TestEmptyPointType()
{
try
{
int* p = NULL
*p = 3
}
catch(...)
{
cout<<"非法地址 *** 作异常" <<endl
}
}
void TestDivZeroType()
{
try
{
int b = 0
int a = 3/b
}
catch(...)
{
cout<<"0除异常" <<endl
}
}
void TestMemoryOutType()
{
int * a = new int[4]
try
{
for (int i = 0i<245i++)
{
a++
}
*a = 3
}
catch(...)
{
cout<<"内存越界异常" <<endl
}
}
int main(int argc, char* argv[])
{
TestEmptyPointType()
//TestDivZeroType()
TestMemoryOutType()
return 1
}
Linux下编程(尤其是服务端程序)若由于内存越界或其他原因产生“非法 *** 作”,会导致程序悄无声息地死去,初学者往往不知道程序死掉的原因。本人也曾饱受程序死不瞑目之苦。其实“非法 *** 作”在绝大多数时候是因为“段错误”,即 SIGSEGV。而找到SIGSEGV信号抛出的位置,也就找到了程序死掉的原因。下面列出一些捕获SIGSEGV的方法。
假设程序名为 myprg,其进程ID(pid)为 2032。方法一:
# ./myprg // 运行程序
# ps -ef | grep myprg // 找出 myprg 的 pid
# gdb myprg 2032 >debug.log // 让 gdb 接管 myprg 的运行
# (gdb) continue
此方法利用gdb调试器捕获SIGSEGV。上例中,将gdb输出信息存入debug.log,关闭终端,gdb并不退出,继续运行直到 myprg 出错退出。gdb将捕获到出错点。方法二:
# ./myprg // 运行程序
# Segment fault (core dumped) // 程序死掉了,系统输出 "Segment fault"
# gdb myprg core // 用 gdb 分析 core 文件
此方法利用core文件,进行事后分析。但前提是保证系统会生成core文件。
# ulimit -a
查看当前core文件大小的限制,若为0,则需将它改为unlimited。
# ulimit -S -c unlimited
或修改 /etc/profile,找到 unlimit -S -c 0,将0改为unlimited,重启系统。
另外,如果程序安装了 SIGSEGV 异常处理函数,那么 gdb myprg core 时显示的并不是真实的出错位置,要想看到真实的出错点,必须暂时去掉异常处理函数。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)