linux查找段错误的方法
(2013-01-05 20:06:43)
标签:
linux段错误it |
分类: 技术学习园地 |
linux下程序段错误排查方法
写一个简单的源程序做为举例:
#include
#include
int main()
{
}
1.最简单的排查方法是使用gdb调试程序。
前提条件:开始调试之前,必须用程序中的调试信息编译要调试的程序。编译时添加 -g。例如gcc -g main.c -o
main
调试步骤:
1)使用gdb运行程序:gdb 可执行程序路径,例如 gdb ./main。会出现如下gdb的信息等。
wd@wd-Lenovo:~/forktest/segfault$ gdb ./main
GNU gdb (Ubuntu/Linaro 7.4-2012.02-0ubuntu2) 7.4-2012.02
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute
it.
There is NO WARRANTY, to the extent permitted by
law.
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from /home/wd/forktest/segfault/main...done.
2)使用run命令,执行程序:
(gdb) run
3)提示如下信息。此处打印了出错的文件,函数名和行号
Starting program: /home/wd/forktest/segfault/main
Program received signal SIGSEGV, Segmentation fault.
0x0804840d in main () at main.c:9
9
4)使用bt命令,察看函数桟
(gdb) bt
#0
2.使用gdb方式调试有时候并非很方便,因为只有使用gdb启动程序或者在程序运行过程中使用gdb去attach程序,才能体现gdb的好处。
此时的方法如下:
1)通过打印内核缓冲区的记录察看程序出错信息,查出信息如下:
wd@wd-Lenovo:~/forktest/segfault$ dmesg
main[9203]: segfault at 0 ip 0804840d sp bfad6100 error 6 in
main[8048000+1000]
注释:这种信息一般都是由内存访问越界造成的,不管是用户态程序还是内核态程序访问越界都会出core,
并在系统日志里面输出一条这样的信息。这条信息的前面分别是访问越界的程序名,进程ID号,访问越界的地址以及当时进程堆栈地址等信息,比较有用的信息是最后的error
number.将error number转化成二进制。
bit2: 值为1表示是用户态程序内存访问越界,值为0表示是内核态程序内存访问越界
bit1: 值为1表示是写操作导致内存访问越界,值为0表示是读操作导致内存访问越界
bit0: 值为1表示没有足够的权限访问非法地址的内容,值为0表示访问的非法地址根本没有对应的页面,也就是无效地址
2)反汇编可执行程序:使用objdump命令,对上面的例子反汇编后结果如下,可以将结果重定向
wd@wd-Lenovo:~/forktest/segfault$ objdump -d ./main
> obj
./main:
Disassembly of section .init:
080482b4 <_init>:

加载中…