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

                下面我們通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)看看怎么通過(guò)GDB來(lái)調(diào)試一個(gè)違規(guī)訪問(wèn)內(nèi)存導(dǎo)致的程序崩潰。這里我們順便講講動(dòng)態(tài)庫(kù)的調(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   ###############

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

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

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

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

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

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

            3)再次執(zhí)行測(cè)試程序
            [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如期而至,但是卻沒(méi)有我們更想見(jiàn)到的core文件!
            原來(lái)系統(tǒng)在默認(rèn)情況下core文件的大小設(shè)置為0,換句話講也就是不產(chǎn)生core文件。我們可以通過(guò) ulimit 命令來(lái)修改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文件的格式,輸出路徑
            通過(guò)下面命令我們還可以指定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 ?? ()

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

            (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清楚的列出了錯(cuò)誤出現(xiàn)的位置:mylib.c的第8行,好了,到那里去改code吧!
            posted on 2010-11-16 10:40 cooelaf 閱讀(1462) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): Linux
             
            A狠狠久久蜜臀婷色中文网| 久久久久久夜精品精品免费啦| 丁香五月网久久综合| 97久久精品无码一区二区天美| 99久久精品九九亚洲精品| 久久久免费观成人影院| 欧美喷潮久久久XXXXx| 热久久国产精品| 久久人人爽人人爽人人片AV高清| 久久久久亚洲av成人网人人软件| 欧美精品久久久久久久自慰| 久久se精品一区精品二区国产| 久久人人爽人人爽人人AV东京热 | 好久久免费视频高清| 久久影院亚洲一区| 色噜噜狠狠先锋影音久久| 伊人热热久久原色播放www| 亚洲国产精品久久久久婷婷软件| 久久狠狠爱亚洲综合影院| 久久久网中文字幕| 青青青青久久精品国产 | 亚洲午夜久久久久久久久电影网| 一本久久久久久久| 99久久无码一区人妻a黑| 一本大道久久香蕉成人网| 日本福利片国产午夜久久| 久久亚洲春色中文字幕久久久| 武侠古典久久婷婷狼人伊人| 久久精品国产半推半就| 精品一区二区久久| 国内精品久久久久伊人av| 人妻精品久久久久中文字幕69| 国产精品久久久香蕉| 麻豆av久久av盛宴av| 亚洲乱码日产精品a级毛片久久| 99久久精品九九亚洲精品| 国产精品久久久久久久久免费| 久久久久亚洲AV片无码下载蜜桃| 一本一本久久A久久综合精品| 久久久久国产精品人妻| 久久亚洲熟女cc98cm|