段错误以及调试方法

---恢复内容开始---

常见内存错误

(1)内存分配(malloc, new)未成功,却使用了它。

解决方法:在使用内存之前检查指针是否为NULL

(2)内存分配成功,但是没有初始化。在定义数组时养成赋0值的习惯。

(3)内存分配成功,也初始化了,操作越过了内存的边界。

(4)忘记释放内存,造成内存泄漏

(5)释放了内存后继续使用,有三种情况:

  • 程序中的对象调用过于复杂,比如:
int *a = new int[10];
int *b = a;

delete b;//已经将a所指向的内存释放
delete a;//又释放一遍,会出现错误
  • 函数return一个局部变量指针,函数结束申请的栈中的资源就会被回收
  • 使用free和delete释放内存后,没有将指针设置为NULL,导致产生野指针

段错误:

简而言之,产生段错误就是访问了错误的内存段,一般是由于没有权限,或者根本就不存在对应的物理地址,尤其常见的是访问0地址。

一般来说,段错误就是指访问的内存超出了系统所给这个程序的内存控件,通常这个值由gdr来保存的,它是一个48为的寄存器,其中的32位用来保存由它指向的gdt表;后13位用来保存相应于gdt的下标;最后3位包括了程序是否在内存中,以及程序的在CPU中的运行级别。指向的gdt是一个以64位单位的表,在这张表中保存着程序运行的代码段、数据段的起始地址,以及与此相应的段限和页面交换还有程序运行级别,还有内存粒度等的信息。一旦这个程序发生了越界访问,CPU就会产生相应的异常保护,于是segment fault就出现了。

方法一:利用gdb逐步查找段错误

GDB调试方法

方法二:分析core文件

本人使用的RedHat 5的系统,禁止了core文件的生成。

使用ulimit -c查看一个系统core的大小限制

ulimit -c unlimited无限制

gcc -g test.c -o  test

./test

出现段错误会显示 (段错误(core dump))

gdb test core

方法三:利用backtrace和objdump进行分析

 1 #include <stdio.h>
 2 #include <execinfo.h>
 3 #include <stdlib.h>
 4 #include <signal.h>
 5
 6 void dummy_function(void)
 7 {
 8     unsigned char * ptr = 0x00;
 9     *ptr = 0x00;
10 }
11
12 void dump(int signo)//利用backstrace来打印信息
13 {
14     void *array[10];
15     size_t size;
16     char **strings;
17     size_t i;
18     size = backtrace(array, 10);
19     strings = backtrace_symbols(array, size);
20     printf("Obtained %zd stack frames.\n", size);
21
22     for (i = 0; i < size; i++)
23     {
24         printf("%s\n", strings[i]);
25     }
26
27     free(strings);
28     exit(0);
29 }
30
31
32 int main()
33 {
34     signal(SIGSEGV, &dump);
35     dummy_function();
36
37     return 0;
38 }

再结合objdump -d a.out反汇编,找出出错地址在哪个函数中(实在是看不懂,但是了解一下吧)

时间: 2024-08-07 21:20:34

段错误以及调试方法的相关文章

段错误以及调试方式

dummy_function(void) { unsigned char * ptr=0x00; *ptr=0x00; } int main() { dummy_function(); return 0; }作为一名熟练的c/c++程序员,以上代码的bug应该是很清楚的,因为它尝试操作地址为0的内存区域,而这个地址区域通常是不可访问的禁区,当然会出错了. 方法1 :利用gdb逐步查找段错误 这种方法也是被大众所熟知并广泛采用的方法,首先我们需要一个带有调试 信息的可执行程序,所以我们加上"-g

linux 段错误常见处理方法

1.如果没有产生core文件,可以查询系统log 通过 sudo cat /var/log/messages |grep segfault 或者 sudo dmesg|grep segfault 获得这种信息一般都是由内存访问越界造成的,不管是用户态程序还是内核态程序访问越界都会出core, 并在系统日志里面输出一条这样的信息.这条信息的前面分别是访问越界的程序名,进程ID号,访问越界的地址以及当时进程堆栈地址等信息,比较有用的信息是 最后的error number. 在上面的信息中,error

C段错误等调试

本文参考 http://stackoverflow.com/questions/2179403/how-do-you-read-a-segfault-kernel-log-message和http://www.slideshare.net/noobyahoo/introduction-to-segmentation-fault-handling-5563036 linux中 遇到 段错误的情况, 多数人会想到core dump, 但是不一定有,其实有其他的办法, 当进程出现这类问题的时候, 使用

gcc编译通过,运行却显示“段错误”的解决方法

?第一次在Liunx上(liunx mint 17)使用gcc编译c文件,竟然提示“找不到stdio.h",经过google后发现执行 sudo apt-get install build-essential 即可,详见:http://slipper-99933.blog.163.com/blog/static/39954044201021651833785/ 正文: ?刚学习了柔性数组,照教程写了用柔性数组生成斐波那契数列,经过一翻修改后gcc编译通过,运行时却提示”段错误“.google一下

Linux环境下段错误的产生原因及调试方法小结(转)

最近在Linux环境下做C语言项目,由于是在一个原有项目基础之上进行二次开发,而且 项目工程庞大复杂,出现了不少问题,其中遇到最多.花费时间最长的问题就是著名的“段错误”(Segmentation Fault).借此机会系统学习了一下,这里对Linux环境下的段错误做个小结,方便以后同类问题的排查与解决. 1. 段错误是什么 一句话来说,段错误是指访问的内存超出了系统给这个程序所设定的内存空间,例如访问了不存在的内存地址.访问了系统保护的内存地址.访问了只读的内存地址等等情况.这里贴一个对于“段

Linux环境下段错误的产生原因及调试方法小结

最近在Linux环境下做C语言项目,由于是在一个原有项目基础之上进行二次开发,而且项目工程庞大复杂,出现了不少问题,其中遇到最多.花费时间最长的问题就是著名的“段错误”(Segmentation Fault).借此机会系统学习了一下,这里对Linux环境下的段错误做个小结,方便以后同类问题的排查与解决. 1. 段错误是什么 一句话来说,段错误是指访问的内存超出了系统给这个程序所设定的内存空间,例如访问了不存在的内存地址.访问了系统保护的内存地址.访问了只读的内存地址等等情况.这里贴一个对于“段错

【转】【调试技巧】Linux环境下段错误的产生原因及调试方法小结

本文转自:http://www.cnblogs.com/panfeng412/archive/2011/11/06/segmentation-fault-in-linux.html 最近在Linux环境下做C语言项目,由于是在一个原有项目基础之上进行二次开发,而且项目工程庞大复杂,出现了不少问题,其中遇到最多.花费时间最长的问题就是著名的“段错误”(Segmentation Fault).借此机会系统学习了一下,这里对Linux环境下的段错误做个小结,方便以后同类问题的排查与解决. 1. 段错误

Linux环境下段错误的产生原因及调试方法小结(转载)

转载自http://www.cnblogs.com/panfeng412/archive/2011/11/06/2237857.html 最近在Linux环境下做C语言项目,由于是在一个原有项目基础之上进行二次开发,而且项目工程庞大复杂,出现了不少问题,其中遇到最多.花费时间 最长的问题就是著名的“段错误”(Segmentation Fault).借此机会系统学习了一下,这里对Linux环境下的段错误做个小结,方便以后同类问题的排查与解决. 1. 段错误是什么 一句话来说,段错误是指访问的内存超

ubuntu segmentation fault 段错误

1.段错误 http://www.cnblogs.com/panfeng412/archive/2011/11/06/2237857.html 2.段错误的调试方法 2.1使用printf输出信息 2.2使用gcc和gdb 2.3使用core文件和gdb ……