• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            酸菜豬蹄的程序人生
            木下編程屯屯燙燙


            作者:<leohe.leohe@gmail.com>

                Linux系統(tǒng)中在應(yīng)用程序運行過程中經(jīng)常會遇到程序突然崩潰,提示:Segmentation fault,這是因為應(yīng)用程序收到了SIGSEGV信號。這個信號提示當(dāng)進(jìn)程發(fā)生了無效的存儲訪問,當(dāng)接收到這個信號時,缺省動作是:終止w/core。 終止w/core的含義是:在進(jìn)程當(dāng)前目錄生成core文件,并將進(jìn)程的內(nèi)存映象復(fù)制到core文件中,core文件的默認(rèn)名稱就是“core”(這是 Unix類系統(tǒng)的一個由來已久的功能)。
                事實上,并不是只有SIGSEGV信號產(chǎn)生coredump,還有下面一些信號也產(chǎn)生coredump:SIGABRT(異常終止)、SIGBUS(硬件 故障)、SIGEMT(硬件故障)、SIGFPE(算術(shù)異常)、SIGILL(非法硬件指令)、SIGIOT(硬件故 障),SIGQUIT,SIGSYS(無效系統(tǒng)調(diào)用),SIGTRAP(硬件故障)等。
                在程序的開發(fā)調(diào)試階段(尤其是大型軟件開發(fā)),發(fā)生程序異常崩潰時常規(guī)的調(diào)試方法常常是無比的痛苦:無窮的log中也不見得有什么有意義的信息。好在GDB提供和利用core文件進(jìn)行調(diào)試的途徑,大大方便了這類問題的調(diào)試。

                下面我們通過一個簡單的例子來看看怎么通過GDB來調(diào)試一個違規(guī)訪問內(nèi)存導(dǎo)致的程序崩潰。這里我們順便講講動態(tài)庫的調(diào)試。

            /******** mylib.h **********/
            #ifndef __MY_LIB_H__
            #define __MY_LIB_H__

            int add(int x, int y);

            #endif // __MY_LIB_H__
            /******** end **********/



            /******** mylib.c **********/
            #include <stdlib.h>
            #include "mylib.h"

            int add(int x, int y)
            {
                char* pc = NULL;
                *pc = 10;

                return x + y;
            }
            /******** end **********/

            /******** main.c **********/

            #include <stdio.h>
            #include <stdlib.h>

            #include "mylib.h"

            int main (void)
            {
                int ret = -1;
                int a = 10, b = 20;
                ret = add(a, b);

                printf("The result is: %d\n", ret);

                return 0;
            }
            /******** end **********/

            #####################################
            # File Name: Makefile
            #
            #####################################

            CC = gcc
            LD = gcc

            all:
                    $(CC) mylib.c -g -I. -fPIC -shared -o libmylib.so
                    $(CC) main.c -g -I. -L. -lmylib -o test

            clean:
                    rm *.so test
            #############   END   ###############

                首先將上面的代碼分別存儲到相應(yīng)的目錄,名稱為:mylib.h、mylib.c、main.c、Makefile。

            1)編譯測試代碼。注)編譯時的 -g 選項是必須的。
            [xxx@yyy]$ make
            gcc mylib.c -g -I. -fPIC -shared -o libmylib.so
            gcc main.c -g -I. -L. -lmylib -o t

            通過ls命令我們可以看到生成了測試程序test.
            [xxx@yyy]$ ls
            libmylib.so main.c Makefile mylib.c mylib.h test

            2)執(zhí)行測試程序
            [xxx@yyy]$ ./test
            ./test: error while loading shared libraries: libmylib.so: cannot open shared object file: No such file or directory

            這個錯誤表明程序在運行階段不能找到相應(yīng)的動態(tài)庫文件,此時需要通過環(huán)境變量 LD_LIBRARY_PATH 來指定運行期動態(tài)庫的搜索目錄,我們的動態(tài)庫就在當(dāng)前目錄,如下:

            [xxx@yyy]$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

            3)再次執(zhí)行測試程序
            [leo@localhost debug]$ ./test
            Segmentation fault
            [leo@localhost debug]$ ls
            libmylib.so main.c Makefile mylib.c mylib.h test

            4)設(shè)置core文件大小
            Segmentation fault如期而至,但是卻沒有我們更想見到的core文件!
            原來系統(tǒng)在默認(rèn)情況下core文件的大小設(shè)置為0,換句話講也就是不產(chǎn)生core文件。我們可以通過 ulimit 命令來修改core文件的大小,unlimited表示不限制core文件的大小,如下(設(shè)置core文件的大小需要root權(quán)限):
            [root@yyy]# ulimit -c unlimited
            [root@yyy]# ./test
            Segmentation fault (core dumped)
            [root@yyy]# ls
            core.2890 libmylib.so main.c Makefile mylib.c mylib.h test

            5)設(shè)置core文件的格式,輸出路徑
            通過下面命令我們還可以指定core文件的命名格式,路徑等(需要root權(quán)限):
            [root@yyy]# echo "core_%e_%s" >/proc/sys/kernel/core_pattern
            [root@yyy]# ./test
            Segmentation fault (core dumped)
            [root@yyy]# ls
            core.2890 core_test_11.2898 libmylib.so main.c Makefile mylib.c mylib.h test

            6)調(diào)試
            [root@yyy]# gdb test core.2890
            GNU gdb Red Hat Linux (6.5-8.fc6rh)
            Copyright (C) 2006 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-redhat-linux-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".

            Core was generated by `./test'.
            Program terminated with signal 11, Segmentation fault.
            Error while mapping shared library sections:
            libmylib.so: Success.
            Reading symbols from /home/xxx/tst/libmylib.so...done.
            Loaded symbols for libmylib.so
            Reading symbols from /lib/i686/libc.so.6...done.
            Loaded symbols for /lib/i686/libc.so.6
            Reading symbols from /lib/ld-linux.so.2...done.
            Loaded symbols for /lib/ld-linux.so.2
            #0 0x00a8969c in ?? ()
            (gdb)

            鍵入GDB命令 where
            (gdb) where
            #0 0x001ec44c in ?? ()
            #1 0x00000000 in ?? ()

            ?? ()并不是我們想看到的,之所以這樣,是因為GDB不能正確加載我們編寫的動態(tài)庫libmylib.so,我們需要在這里設(shè)置GDB的動態(tài)庫搜索路徑,如下:

            (gdb) set solib-search-path .
            Reading symbols from /home/xxx/test/tst/libmylib.so...done.
            Loaded symbols for /home/xxx/test/tst/libmylib.so
            Reading symbols from /lib/i686/libc.so.6...done.
            Loaded symbols for /lib/i686/libc.so.6
            Reading symbols from /lib/ld-linux.so.2...done.
            Loaded symbols for /lib/ld-linux.so.2

            可以看到GDB已經(jīng)加載了libmylib.so,再次鍵入where命令:
            (gdb) where
            #0 0x001ec44c in add (x=10, y=20) at mylib.c:8
            #1 0x0804847c in main () at main.c:12
            (gdb)

            這次我們期待的結(jié)果出現(xiàn)了,GDB清楚的列出了錯誤出現(xiàn)的位置:mylib.c的第8行,好了,到那里去改code吧!
            posted on 2010-11-16 10:40 cooelaf 閱讀(1473) 評論(0)  編輯 收藏 引用 所屬分類: Linux
             
            久久99精品久久久久久噜噜 | 久久91精品综合国产首页| 国产成人久久激情91| 99久久成人18免费网站| 要久久爱在线免费观看| 日韩人妻无码精品久久免费一| 久久发布国产伦子伦精品| 国产午夜精品理论片久久| 亚洲色欲久久久久综合网| 国产亚洲精品自在久久| 久久亚洲中文字幕精品一区| 无码专区久久综合久中文字幕 | 久久久久波多野结衣高潮| 久久久久成人精品无码中文字幕 | 国产精品久久久久jk制服| 免费一级欧美大片久久网 | 亚洲精品无码专区久久久| 国内精品久久久久久麻豆| 久久国产色AV免费看| 久久久精品人妻无码专区不卡| 99久久综合狠狠综合久久止| 国产精品成人精品久久久| 久久国产精品一国产精品金尊| 少妇人妻88久久中文字幕| 99久久国产免费福利| 99久久99这里只有免费的精品| 99久久这里只精品国产免费| 人人狠狠综合久久亚洲婷婷| 麻豆AV一区二区三区久久| 国产色综合久久无码有码| 欧美一级久久久久久久大| 久久99精品久久久久久秒播| 青青草原1769久久免费播放| 精品久久久久久亚洲精品| 久久棈精品久久久久久噜噜| 人妻无码αv中文字幕久久| 伊人久久综合无码成人网| 久久www免费人成看片| 伊人久久综合无码成人网| 99蜜桃臀久久久欧美精品网站 | 国产精品永久久久久久久久久|