<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    一江春水向東流

    做一個(gè)有思想的人,期待與每一位熱愛(ài)思考的人交流,您的關(guān)注是對(duì)我最大的支持。

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      44 隨筆 :: 139 文章 :: 81 評(píng)論 :: 0 Trackbacks

    GDB輕松調(diào)試

    一、引言
    在了解GDB可以做什么,怎么做之前,讓我們先來(lái)看看為什么要用GDB,或者說(shuō)對(duì)調(diào)試工具有什么期望。

    一般我們使用GDB(或其他調(diào)試工具)是為了發(fā)現(xiàn)程序bug,更經(jīng)常地是在已知程序有錯(cuò)的情況下定位bug。既然這樣,我們就需要跟蹤程序的執(zhí)行情況,查看程序執(zhí)行是否正常,當(dāng)然這就需要有個(gè)讓我們與執(zhí)行程序交互的環(huán)境,調(diào)試工具提供一個(gè)能讓程序在你的掌控下執(zhí)行,并讓你能夠查看一些執(zhí)行過(guò)程中的“內(nèi)幕信息”的環(huán)境。

    為了查看程序運(yùn)行過(guò)程中的狀態(tài),我們就希望程序能在適當(dāng)?shù)奈恢没蛘咴谝欢ǖ臈l件下能夠暫停運(yùn)行;為此,調(diào)試工具提供了斷點(diǎn)、查看變量/表達(dá)式、顯示程序棧等功能。看了某個(gè)點(diǎn)的“內(nèi)幕”后,我們還期望更多,所以要能控制程序運(yùn)行才行,這就要求斷點(diǎn)、繼續(xù)運(yùn)行、單步(多步)運(yùn)行、進(jìn)入函數(shù)運(yùn)行等功能,在某些情況下,還需要通過(guò)修改當(dāng)前的執(zhí)行環(huán)境(變量等)來(lái)達(dá)到期望的執(zhí)行順序。也就是說(shuō),光看著是不夠的,還需要能改才行。

    理解了這些問(wèn)題后,我們就明白GDB的各個(gè)功能的用意了,自然也就明白該如何使用調(diào)試工具了。當(dāng)然,要讓GDB有效的發(fā)揮作用,還是需要一定的經(jīng)驗(yàn)與技巧,而這主要靠實(shí)踐,學(xué)習(xí)資料(包括本文)充其量只能幫你一把(小心別讓它幫倒忙)。

    總而言之,我們首先要明白使用調(diào)試工具的目的和用意,才能理解它的各項(xiàng)功能,才能借助它快速有效的發(fā)現(xiàn)問(wèn)題;否則,即使工具再?gòu)?qiáng)大,你也不知道該如何使用才好。

    另外要多結(jié)合使用代碼檢視、運(yùn)行日志、測(cè)試工具等方法來(lái)發(fā)現(xiàn)潛在的問(wèn)題,提供程序的質(zhì)量。這些問(wèn)題將在另文探討,先做個(gè)廣告。
    ?
    ?
    二、GDB能做什么
    GDB可以用來(lái)調(diào)試C、C++、Modula-2的程序。一般來(lái)說(shuō),GDB能做的事大致可以分為四類:

    1、啟動(dòng)程序,按指定的方式執(zhí)行程序。
    2、在指定條件下使程序暫停.
    3、當(dāng)程序被停住時(shí),可以檢查此時(shí)你的程序中的變化。
    4、改變程序中的變量或執(zhí)行順序來(lái)試驗(yàn)。
    ?
    ?
    三、GDB使用概述
    首先要了解的是gdb的help命令,因?yàn)槟憧赡苡洸蛔「鱾€(gè)命令的語(yǔ)法和用途,但只要能正確使用help命令,你就不需要任何其它的gdb資料。

    啟動(dòng)gdb后,輸入help

    [eric@linux eric]$ gdb
    GNU gdb Red Hat Linux (5.3.90-0.20030710.40rh)
    Copyright 2003 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".
    (gdb) help
    List of classes of commands:

    aliases -- Aliases of other commands
    breakpoints -- Making program stop at certain points
    data -- Examining data
    files -- Specifying and examining files
    internals -- Maintenance commands
    obscure -- Obscure features
    running -- Running the program
    stack -- Examining the stack
    status -- Status inquiries
    support -- Support facilities
    tracepoints -- Tracing of program execution without stopping the program
    user-defined -- User-defined commands

    Type "help" followed by a class name for a list of commands in that class.
    Type "help" followed by command name for full documentation.
    Command name abbreviations are allowed if unambiguous.
    (gdb)


    如上文顯示,gdb的命令很多,所以把它分成許多個(gè)種類。help命令只是例出gdb的命令種類,如果要看某類中的命令,可以使用help <class> 命令,如:help breakpoints,查看設(shè)置斷點(diǎn)的所有命令。當(dāng)如也可以直接help <command>來(lái)查看某個(gè)命令的具體信息。


    gdb 技巧:在記不清整個(gè)命令時(shí),可以只打命令的前一個(gè)或幾個(gè)字符,然后敲擊兩次TAB鍵來(lái)列出所有以這幾個(gè)字符開(kāi)頭的命令;另為,大多命令都有縮寫(xiě),如b同 break,c同continue,n同next,p同print等。另為,一個(gè)命令在輸入能唯一標(biāo)示命令的前綴后,按一下TAB鍵就能補(bǔ)齊命令的全稱,比如輸入ba后按一下TAB鍵,就自動(dòng)補(bǔ)齊為backtrace,輸入pr后按一下TAB鍵就補(bǔ)齊為print。


    為調(diào)試編譯代碼

    為了使 gdb 正常工作, 你必須使你的程序在編譯時(shí)包含調(diào)試信息. 調(diào)試信息包含你程序里的每個(gè)變量的類型和在可執(zhí)行文件里的地址映射以及源代碼的行號(hào). gdb 利用這些信息使源代碼和機(jī)器碼相關(guān)聯(lián).
    在編譯時(shí)用 -g 選項(xiàng)打開(kāi)調(diào)試選項(xiàng).

    在GDB中運(yùn)行程序


    當(dāng)以gdb <program>方式啟動(dòng)gdb后,可以使用r或是run命令運(yùn)行程序。在程序運(yùn)行之前,你有可能需要設(shè)置下面四方面的事。

    1、程序運(yùn)行參數(shù)。
    set args 可指定運(yùn)行時(shí)參數(shù)。(如:set args 10 20 30 40 50)
    show args 命令可以查看設(shè)置好的運(yùn)行參數(shù)。

    2、運(yùn)行環(huán)境。
    path <dir> 可設(shè)定程序的運(yùn)行路徑。
    show paths 查看程序的運(yùn)行路徑。
    set environment varname [=value] 設(shè)置環(huán)境變量。如:set env USER=hchen
    show environment [varname] 查看環(huán)境變量。

    3、工作目錄。
    cd <dir> 相當(dāng)于shell的cd命令。
    pwd 顯示當(dāng)前的所在目錄。

    4、程序的輸入輸出。
    info terminal 顯示你程序用到的終端的模式。
    使用重定向控制程序輸出。如:run > outfile
    tty命令可以指寫(xiě)輸入輸出的終端設(shè)備。如:tty /dev/ttyb


    調(diào)試已運(yùn)行的程序


    可以有兩種方法調(diào)試已運(yùn)行程序:
    1、用ps查看正在運(yùn)行的程序的進(jìn)程ID,然后用gdb <program> PID格式掛接正在運(yùn)行的程序。
    2、先用gdb <program>關(guān)聯(lián)上程序,并進(jìn)行g(shù)db,在gdb中用attach命令來(lái)掛接程序正在運(yùn)行的進(jìn)程。detach可用來(lái)取消掛接的進(jìn)程。

    暫停/恢復(fù)程序運(yùn)行


    你可以使用info program 來(lái)查看程序的當(dāng)前的執(zhí)行狀態(tài)。

    在gdb中,我們可以有以下幾種暫停方式:斷點(diǎn)(BreakPoint)、觀察點(diǎn)(WatchPoint)、捕捉點(diǎn)(CatchPoint)、信號(hào)(Signals)、線程停止(Thread Stops)。如果要恢復(fù)程序運(yùn)行,可以使用c或是continue命令。

    查看變量/表達(dá)式的值

    可以使用print expr(或p expr)來(lái)查看程序變量/表達(dá)式的值

    顯示程序棧

    可以使用backtrace(或bt)來(lái)顯示程序棧

    單步跟蹤

    next [n] 執(zhí)行下一條(或n條)語(yǔ)句,不進(jìn)入子程序

    step [n] 執(zhí)行下一條(或n條)語(yǔ)句,進(jìn)入子程序,可用finish從子程序返回

    ?
    ?
    ?
    四、GDB常用命令
    backtrace 顯示程序中的當(dāng)前位置和表示如何到達(dá)當(dāng)前位置的棧跟蹤(同義詞:where)
    breakpoint 在程序中設(shè)置一個(gè)斷點(diǎn)
    cd 改變當(dāng)前工作目錄
    clear 刪除剛才停止處的斷點(diǎn)
    commands 命中斷點(diǎn)時(shí),列出將要執(zhí)行的命令
    continue 從斷點(diǎn)開(kāi)始繼續(xù)執(zhí)行
    delete 刪除一個(gè)斷點(diǎn)或監(jiān)測(cè)點(diǎn);也可與其他命令一起使用
    display 程序停止時(shí)顯示變量和表達(dá)時(shí)
    down 下移棧幀,使得另一個(gè)函數(shù)成為當(dāng)前函數(shù)
    frame 選擇下一條continue命令的幀
    info 顯示與該程序有關(guān)的各種信息
    jump 在源程序中的另一點(diǎn)開(kāi)始運(yùn)行
    kill 異常終止在gdb 控制下運(yùn)行的程序
    list 列出相應(yīng)于正在執(zhí)行的程序的原文件內(nèi)容
    next 執(zhí)行下一個(gè)源程序行,從而執(zhí)行其整體中的一個(gè)函數(shù)
    print 顯示變量或表達(dá)式的值
    pwd 顯示當(dāng)前工作目錄
    pype 顯示一個(gè)數(shù)據(jù)結(jié)構(gòu)(如一個(gè)結(jié)構(gòu)或C++類)的內(nèi)容
    quit 退出gdb
    reverse-search 在源文件中反向搜索正規(guī)表達(dá)式
    run 執(zhí)行該程序
    search 在源文件中搜索正規(guī)表達(dá)式
    set variable 給變量賦值
    signal 將一個(gè)信號(hào)發(fā)送到正在運(yùn)行的進(jìn)程
    step 執(zhí)行下一個(gè)源程序行,必要時(shí)進(jìn)入下一個(gè)函數(shù)
    undisplay display命令的反命令,不要顯示表達(dá)式
    until 結(jié)束當(dāng)前循環(huán)
    up 上移棧幀,使另一函數(shù)成為當(dāng)前函數(shù)
    watch 在程序中設(shè)置一個(gè)監(jiān)測(cè)點(diǎn)(即數(shù)據(jù)斷點(diǎn))
    whatis 顯示變量或函數(shù)類型


    命令的具體使用方法請(qǐng)用上面介紹的help查詢,看不明白的地方就多試試。
    ?
    ?
    五、用例子說(shuō)話
    本文是打算寫(xiě)個(gè)簡(jiǎn)單的程序作為例子講解的,后來(lái)一想:“太假”,就講一個(gè)前幾天我的實(shí)際調(diào)試經(jīng)歷吧,因?yàn)楫?dāng)時(shí)沒(méi)抓圖,這里就用文字描述了,請(qǐng)讀者注意其中的思路和方法,具體的一些操作就要?jiǎng)跓┳约喝?shí)踐了

    背景:在將一個(gè)linux程序(姑且就叫A吧)重redhat 9.0移植到redhat es時(shí)發(fā)現(xiàn)程序core了

    開(kāi)始了,呵呵:

    1、首先我查看了程序日志,找到引起程序core掉的數(shù)據(jù)(一個(gè)網(wǎng)頁(yè));//所以說(shuō)日志很重要

    2、下載了那個(gè)網(wǎng)頁(yè),用它作為輸入,結(jié)果必core;//確認(rèn)出錯(cuò)環(huán)境

    3、用gdb啟動(dòng)程序,然后觸發(fā)錯(cuò)誤后,用bt查看程序棧,記錄棧中的函數(shù)調(diào)用鏈以及出錯(cuò)的代碼行數(shù)

    4、在用gdb啟動(dòng)程序,在出錯(cuò)行前設(shè)斷點(diǎn),運(yùn)行之,再觸發(fā)錯(cuò)誤

    5、使用next和step精確定位到出錯(cuò)行

    6、print一個(gè)指針變量,發(fā)現(xiàn)不是NULL,再看指針?biāo)附Y(jié)構(gòu)的各個(gè)變量也正常

    7、好像沒(méi)錯(cuò)呀,呵呵,此處是個(gè)循環(huán),繼續(xù)單步便重復(fù)6

    8、發(fā)現(xiàn)循環(huán)中指針遞減,懷疑指針?biāo)笖?shù)組越界,打印數(shù)組起始位置地址

    9、繼續(xù)循環(huán)一直到出錯(cuò),打印指針變量,發(fā)現(xiàn)其指向的地址低于數(shù)組起始位置地址,真的越界了

    10、初步算是找到了,查看程序源碼,發(fā)現(xiàn)循環(huán)中沒(méi)有判斷該指針是否低于數(shù)組起始位置地址

    11、修改代碼后重新運(yùn)行,程序不core了

    12、將新程序放到正常執(zhí)行環(huán)境下工作,長(zhǎng)時(shí)間運(yùn)行后沒(méi)有發(fā)現(xiàn)該問(wèn)題重現(xiàn),確認(rèn)解決問(wèn)題

    13、通知出錯(cuò)部分(一個(gè)功能函數(shù)庫(kù))的作者問(wèn)題找到、原因

    注:為簡(jiǎn)單起見(jiàn)省略了過(guò)程中的一些因系統(tǒng)特殊性引起的工作
    ?

    posted on 2007-01-19 21:17 allic 閱讀(482) 評(píng)論(0)  編輯  收藏

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 国产精品午夜免费观看网站| 四虎成年永久免费网站 | 亚洲高清中文字幕综合网| 国产精品视频免费| 免费亚洲视频在线观看| 久久亚洲精品中文字幕无码| 欧美a级在线现免费观看| 一级人做人a爰免费视频| 亚洲一区二区三区91| 久久亚洲国产成人影院网站| 99久久免费观看| 色哟哟国产精品免费观看| 亚洲综合激情九月婷婷| 亚洲精品乱码久久久久久不卡 | 国产乱子精品免费视观看片| 精品一区二区三区无码免费直播| 久久亚洲国产成人亚| 亚洲AⅤ优女AV综合久久久| 久久九九兔免费精品6| 国产精品小视频免费无限app| 亚洲乱码日产精品BD在线观看| 中文字幕第一页亚洲| 精品国产麻豆免费网站| 99re热精品视频国产免费| 一道本不卡免费视频| 亚洲va久久久久| 久久亚洲日韩精品一区二区三区| 亚洲天堂免费在线视频| 最近中文字幕免费mv视频7| 一级毛片**不卡免费播| 国产免费人成视频在线播放播 | 亚洲精品av无码喷奶水糖心| 4480yy私人影院亚洲| 亚洲无人区午夜福利码高清完整版| 四虎影视免费在线| 成人黄色免费网站| 精品熟女少妇a∨免费久久| 免费a级毛片无码a∨免费软件 | 国产午夜精品久久久久免费视 | 亚洲一区二区三区深夜天堂| 亚洲国产成人久久精品影视|