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已經超出了棧的下限範圍。