core檔案與gdb調試

來源:互聯網
上載者:User

標籤:core gdb 調試


本文簡單介紹core檔案與gdb調試core檔案的方法


概要:

    1. core 檔案

    2. 配置core程式崩潰時產生檔案

    3. 可修改core檔案名稱

   4. 產生core檔案的情形

    5. gdb調試core檔案

        a) gdb -c <xxx.core> [可執行程式]

        b) gdb命令:backtrace / bt 

        c) gdb命令:up/down/frame

        d) gdb命令:info locals

        e) gdb命令:info args

        f) gdb命令:print <變數名> / print *<變數名>



1. core 檔案


    linux/unix下,可執行程式崩潰時會產生core檔案。core檔案是記憶體映象,可用於偵錯工具找出程式崩潰的原因。


2. 配置core程式崩潰時產生檔案


    linux/unix下,通過limit -a,可以查看系統是否對可程式的崩潰產生core檔案。其中core file size 便是指產生core檔案的大小。下面是freebsd系統中輸出limit -a 輸出的一行,unlimited表示不限制,如果 unlimited 為 1024,則表示產生core檔案最大為 1024塊,每塊大小為512位元組。如果為0,則表示不產生core檔案。

core file size      (512-blocks, -c)  unlimited

core file size      (512-blocks, -c)  1024

core file size      (512-blocks, -c)  0


    通過limit命令,可以改變設定。如 ulimit -c unlimited 或 limit -c 1024等。


3. 可修改core檔案名稱


    core檔案產生於程式的工作目錄,不通系統命名不一樣 freebsd 下,預設命名為 程式名.core ,這個名稱是可以修改的。freebsd下,通過 man core 可以知道,通過sysctl可以查看core檔案名稱的規則和對其進行修改。下面是指core檔案名稱組成是 程式名.core。


[email protected]:/ # sysctl -a | grep corefile

kern.corefile: %N.core


    freebsd下查看 man core,可以知道core檔案命名時可用的規則:


     The name of the file is controlled via the sysctl(8) variable

     kern.corefile.  The contents of this variable describes a filename to

     store the core image to.  This filename can be absolute, or relative

     (which will resolve to the current working directory of the program gen-

     erating it).


     The following format specifiers may be used in the kern.corefile sysctl

     to insert additional information into the resulting core file name:

          %H          Machine hostname.

          %I          An index starting at zero until the sysctl debug.ncores

                      is reached.  This can be useful for limiting the number

                      of corefiles generated by a particular process.

          %N          process name.

          %P          processes PID.

          %U          process UID.



4. 產生core檔案的情形


    程式在運行時,發生致命錯誤導致程式崩潰,會產生core檔案。當系統捕獲到一些訊號如 SIGSEGV 等訊號,就會生產core檔案。


    通過man signal,可以查看到什麼資訊會產生core:


     Num   Name         Default Action       Description

     1     SIGHUP       terminate process    terminal line hangup

     2     SIGINT       terminate process    interrupt program

     3     SIGQUIT      create core image    quit program

     4     SIGILL       create core image    illegal instruction

     5     SIGTRAP      create core image    trace trap

     6     SIGABRT      create core image    abort program (formerly SIGIOT)

     7     SIGEMT       create core image    emulate instruction executed

     8     SIGFPE       create core image    floating-point exception

     9     SIGKILL      terminate process    kill program

     10    SIGBUS       create core image    bus error

     11    SIGSEGV      create core image    segmentation violation

     12    SIGSYS       create core image    non-existent system call invoked


    最常見的程式崩潰的原因便是 SIGSEGV(非法訪問記憶體)。


5. gdb調試core檔案


    1) 程式在編碼時,加上 -g 選項來增加調試資訊。

    2) 用gdb對core檔案進行調試,查看程式運行狀態。


下面列舉一些常用的命令:


a) gdb -c <xxx.core> [可執行程式]


    運行gdb,調度core檔案。如下面是我的可執行程式所在的目錄:


[email protected]:~/test/core_statck # ls

core_stack      core_stack.core core_stack.cpp


    core_stack.cpp    源檔案

    core_stack          由源檔案編譯出來的可執行程式

    core_stack.core   core_stack產生的core檔案


    輸入命令後,gdb就會運行並輸出很多資訊,這些資訊基本上是載入庫的資訊。最後還會輸出最後一個stack中的資訊。此時gdb是處於第0棧狀態。


[email protected]:~/test/core_statck # gdb -c core_stack.core core_stack

GNU gdb 6.1.1 [FreeBSD]

Copyright 2004 Free Software Foundation, Inc.

GDB is free software, covered by the GNU General Public License, and you are

welcome to change it and/or distribute copies of it under certain conditions.

Type "show copying" to see the conditions.

There is absolutely no warranty for GDB.  Type "show warranty" for details.

This GDB was configured as "i386-marcel-freebsd"...

Core was generated by `core_stack‘.

Program terminated with signal 6, Aborted.

Reading symbols from /usr/lib/libc++.so.1...done.

Loaded symbols for /usr/lib/libc++.so.1

Reading symbols from /lib/libcxxrt.so.1...done.

Loaded symbols for /lib/libcxxrt.so.1

Reading symbols from /lib/libm.so.5...done.

Loaded symbols for /lib/libm.so.5

Reading symbols from /lib/libgcc_s.so.1...done.

Loaded symbols for /lib/libgcc_s.so.1

Reading symbols from /lib/libc.so.7...done.

Loaded symbols for /lib/libc.so.7

Reading symbols from /libexec/ld-elf.so.1...done.

Loaded symbols for /libexec/ld-elf.so.1

#0  0x2829a467 in kill () from /lib/libc.so.7

(gdb) 


b) gdb命令:backtrace / bt 


    gdb命令 bt 可以輸出程式崩潰前棧上的資訊,主要是程式的調用棧。


(gdb) bt

#0  0x2829a467 in kill () from /lib/libc.so.7

#1  0x2829a3f7 in raise () from /lib/libc.so.7

#2  0x28298b06 in abort () from /lib/libc.so.7

#3  0x282797f8 in __assert () from /lib/libc.so.7

#4  0x08049de0 in MyDump::print (this=0xbfbfecd8, x=4, core=false) at core_stack.cpp:13

#5  0x080491bd in MyDump::detaildump (this=0xbfbfecd8, a=111, b=222) at core_stack.cpp:35

#6  0x08049166 in MyDump::dump (this=0xbfbfecd8, level=0, a=111, b=222) at core_stack.cpp:30

#7  0x08049140 in MyDump::dump (this=0xbfbfecd8, level=1, a=111, b=222) at core_stack.cpp:28

#8  0x08049140 in MyDump::dump (this=0xbfbfecd8, level=2, a=111, b=222) at core_stack.cpp:28

#9  0x08049140 in MyDump::dump (this=0xbfbfecd8, level=3, a=111, b=222) at core_stack.cpp:28

#10 0x0804928f in main () at core_stack.cpp:46


    由上面輸出可以看出,程式的調用情況,同時還會輸出源檔案中對應的行號。


c) gdb命令:up/down/frame


up: 進行上一棧

down: 進入下一棧

frame N: 進行第N棧


這三個命令主要是使用者切換gdb當前所處於的棧。gdb處理某一棧的狀態時,便可以通過info,print等命令來查看棧中的資訊。


d) gdb命令:info locals


查看局部變數,一個很有用的命令。下面可以看到,函數內有一個局部變數lev,值為2


(gdb) info locals

lev = 2


e) gdb命令:info args


    查看函數參數,一個很有用的命令。下面可以看到函數的入參有 this, level, a, b 以及它們的值。


(gdb) info args

this = (MyDump *) 0xbfbfecd8

level = 2

a = 111

b = 222


f) gdb命令:print <變數名> / print *<變數名>


    查看變數值和指標所指變數的值,一個很有用的命令。print 可以列印當前棧可見的變數,包括局部變數、函數入參、全域變數等。下面是輸出this指標的對象,this所指對象有一個成員變數m_n,值為4


(gdb) print *this

$6 = {m_n = 4}


    info locals, info args, print 三個命令配合起來,基本上很容易瞭解到程式core時的目前狀態,定位core的原因。


    上面的命令,大部分情況都可以定位出程式core的問題了。但是對於複雜的棧情況或是棧中有資料被破壞,這是比較能發查出的。更多的命令和用法,需要查看man gdb 和 gdb 命令 help 來瞭解。


本文出自 “chhquan” 部落格,請務必保留此出處http://chhquan.blog.51cto.com/1346841/1711225

core檔案與gdb調試

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.