linux下应用程序中经常会发生段错误段错误基本上是由于访问非法内存所导致的如栈溢出、数组越界访问、malloc/free内存所引起的。在linux下发生段错误时会生成core dump核心转储文件里面记录了发生段错误时的函数调用关系。
ubuntu14.04下默认发生段错误时并不产生核心转储文件需要额外的配置通过命令
ulimit -c查看是否允许的core dump文件大小。如果只是临时需要用到可以使用命令ulimit -c unlimited临时打开则发生段错误时会在当前目录下产生core文件。
若是需要配置一直生效并指定core文件生成路径和一些其他的信息可以用如下命令
在etc/sysctl.conf目录中添加
kernel.core_pattern=/var/coredump/%t-%e-%p-%c.core
kernel.core_uses_pid=0
#sysctl -p
1、栈溢出
在ubuntu上默认的栈空间大小为8192kb应用程序的栈超过这个值就会发生段错误可以通过命令ulimit -s来查看设置的栈的大小。ubuntu14.04 32位 执行如下程序
#include <stdio.h> #include <unistd.h> #include <string.h> void call_fault(void) { char array[9 * 1024 * 1024]; memset(array, 0, sizeof(array)); } void call_test(void) { int a; a = 1; call_fault(); } int main() { call_test(); return 0; }
root@zhuzhu:test_work#gcc -g -Wall stack_out.c
root@zhuzhu:test_work# ./a.out
Segmentation fault (core dumped)
执行过后会在当前目录下生成core文件
root@zhuzhu:test_work# gdb ./a.out core ----->调试开始
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./a.out...done.
warning: exec file is newer than core file.
[New LWP 12155]
Core was generated by `./a.out‘.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x080484bc in __libc_csu_init () ---->从上面的信息来看并没有给出什么有效信息
(gdb)bt full
Python Exception <class ‘gdb.MemoryError‘> Cannot access memory at address 0xbf359d20:
#0 0x080484bc in __libc_csu_init ()
No symbol table info available.
Cannot access memory at address 0xbf359d20 ---->从这里看栈帧好像被破坏了给出的有效信息是没有权限访问地址0xbf359d20首先来查看一下程序内存地址映射
(gdb)
(gdb) info proc mappings ---->栈已经被破坏无法得到stack信息
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x8048000 0x8049000 0x1000 0x0 /root/work/test_work/a.out
0x8049000 0x804a000 0x1000 0x0 /root/work/test_work/a.out
0x804a000 0x804b000 0x1000 0x1000 /root/work/test_work/a.out
0xb757d000 0xb7725000 0x1a8000 0x0 /lib/i386-linux-gnu/libc-2.19.so
0xb7725000 0xb7727000 0x2000 0x1a8000 /lib/i386-linux-gnu/libc-2.19.so
0xb7727000 0xb7728000 0x1000 0x1aa000 /lib/i386-linux-gnu/libc-2.19.so
0xb7747000 0xb7767000 0x20000 0x0 /lib/i386-linux-gnu/ld-2.19.so
0xb7767000 0xb7768000 0x1000 0x1f000 /lib/i386-linux-gnu/ld-2.19.so
(gdb)
(gdb) i reg
eax 0x8048610 134514192
ecx 0x8048615 134514197
edx 0x14 20
ebx 0xb7727000 -1217236992
esp 0xbf359d10 0xbf359d10 ----->查看栈指针指向的位置
ebp 0xbfc59d38 0xbfc59d38
esi 0x0 0
edi 0x0 0
eip 0x80484bc 0x80484bc <__libc_csu_init+12>
eflags 0x10246 [ PF ZF IF RF ]
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51
退出gdb后执行gdb ./a.out
(gdb) quit ---->退出gdb
root@zhuzhu:test_work# gdb ./a.out
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./a.out...done.
(gdb) esp 0xbf359d100xbf359d10
Undefined command: "esp". Try "help".
(gdb) start
Temporary breakpoint 1 at 0x80484a2: file stack_out.c, line 22.
Starting program: /root/work/test_work/a.out
‘
Temporary breakpoint 1, main () at stack_out.c:22
22 call_test();
(gdb) info proc mappings
process 12403
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x8048000 0x8049000 0x1000 0x0 /root/work/test_work/a.out
0x8049000 0x804a000 0x1000 0x0 /root/work/test_work/a.out
0x804a000 0x804b000 0x1000 0x1000 /root/work/test_work/a.out
0xb7e13000 0xb7e14000 0x1000 0x0
0xb7e14000 0xb7fbc000 0x1a8000 0x0 /lib/i386-linux-gnu/libc-2.19.so
0xb7fbc000 0xb7fbe000 0x2000 0x1a8000 /lib/i386-linux-gnu/libc-2.19.so
0xb7fbe000 0xb7fbf000 0x1000 0x1aa000 /lib/i386-linux-gnu/libc-2.19.so
0xb7fbf000 0xb7fc2000 0x3000 0x0
0xb7fd8000 0xb7fda000 0x2000 0x0
0xb7fda000 0xb7fdc000 0x2000 0x0 [vvar]
0xb7fdc000 0xb7fde000 0x2000 0x0 [vdso]
0xb7fde000 0xb7ffe000 0x20000 0x0 /lib/i386-linux-gnu/ld-2.19.so
0xb7ffe000 0xb7fff000 0x1000 0x1f000 /lib/i386-linux-gnu/ld-2.19.so
0xb7fff000 0xb8000000 0x1000 0x20000 /lib/i386-linux-gnu/ld-2.19.so
0xbffdf000 0xc0000000 0x21000 0x0 [stack] ----->可以看到栈的范围
(gdb)
有上面的调试信息可以知道但发生段错误是sp指针是指向0xbf359d10已经超出了栈的下限范围。
本文出自 “12128867” 博客,请务必保留此出处http://12138867.blog.51cto.com/12128867/1914119
原文地址:http://12138867.blog.51cto.com/12128867/1914119