|
在 Windows 下我們已經(jīng)習(xí)慣了用 Windbg 之類的工具調(diào)試 dump 文件,從而分析并排除程序運(yùn)行時(shí)錯(cuò)誤。在 Linux 下我們同樣可以完成類似的工作 —— Core Dump。 我們先看看相關(guān)的設(shè)置。 $ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 20 file size (blocks, -f) unlimited pending signals (-i) 16382 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) unlimited virtual memory (kbytes, -v) unlimited file locks (-x) unlimited "core file size (blocks, -c) 0" 意味著在程序崩潰時(shí)不會(huì)生成 core dump 文件,我們需要修改一下設(shè)置。如果你和我一樣懶得修改配置文件,那么就輸入下面這樣命令吧。 $ sudo sh -c "ulimit -c unlimited; ./test" # test 是可執(zhí)行文件名。 等等…… 我們還是先準(zhǔn)備個(gè)測(cè)試目標(biāo)。 #include <stdio.h>
#include <stdlib.h>
void test()
{
char* s = "abc";
*s = 'x';
}
int main(int argc, char** argv)
{
test();
return (EXIT_SUCCESS);
}很顯然,我們?cè)?test() 里面寫了一個(gè)不該寫的東東,這無(wú)疑會(huì)很嚴(yán)重。生成可執(zhí)行文件后,執(zhí)行上面的命令。 $ sudo sh -c "ulimit -c unlimited; ./test" Segmentation fault (core dumped) $ ls -l total 96 -rw------- 1 root root 167936 2010-01-06 13:30 core -rwxr-xr-x 1 yuhen yuhen 9166 2010-01-06 13:16 test 這個(gè) core 文件就是被系統(tǒng) dump 出來(lái)的,我們分析目標(biāo)就是它了。 $ sudo gdb test core GNU gdb (GDB) 7.0-ubuntu Copyright (C) 2009 Free Software Foundation, Inc. Reading symbols from .../dist/Debug/test...done. warning: Can't read pathname for load map: Input/output error. Reading symbols from /lib/tls/i686/cmov/libpthread.so.0... ...done. (no debugging symbols found)...done. Loaded symbols for /lib/tls/i686/cmov/libpthread.so.0 Reading symbols from /lib/tls/i686/cmov/libc.so.6... ...done. (no debugging symbols found)...done. Loaded symbols for /lib/tls/i686/cmov/libc.so.6 Reading symbols from /lib/ld-linux.so.2... ...done. (no debugging symbols found)...done. Loaded symbols for /lib/ld-linux.so.2 Core was generated by `./test'. Program terminated with signal 11, Segmentation fault. #0 0x080483f4 in test () at main.c:16 warning: Source file is more recent than executable. 16 *s = 'x'; 最后這幾行提示已經(jīng)告訴我們錯(cuò)誤的原因和代碼位置,接下來(lái)如何調(diào)試就是 gdb 的技巧了,可以先輸入 "where" 看看調(diào)用堆棧。 (gdb) where #0 0x080483f4 in test () at main.c:16 #1 0x08048401 in main (argc=1, argv=0xbfd53e44) at main.c:22 (gdb) p s $1 = 0x80484d0 "abc" (gdb) info files
Symbols from ".../dist/Debug/test".
Local core dump file:
Local exec file:
`.../dist/Debug/test', file type elf32-i386.
Entry point: 0x8048330
0x08048134 - 0x08048147 is .interp
... ...
0x08048330 - 0x080484ac is .text
0x080484ac - 0x080484c8 is .fini
0x080484c8 - 0x080484d4 is .rodata很顯然 "abc" 屬于 .rodata,嚴(yán)禁調(diào)戲。 ---------------- 附:如果你調(diào)試的是 Release (-O2) 版本,而且刪除(strip)了符號(hào)表,那還是老老實(shí)實(shí)數(shù)匯編代碼吧??梢娪?Debug 版本試運(yùn)行是很重要滴?。?! |
|
|
來(lái)自: just_person > 《調(diào)試排錯(cuò)》