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

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

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

    weidagang2046的專欄

    物格而后知致
    隨筆 - 8, 文章 - 409, 評(píng)論 - 101, 引用 - 0
    數(shù)據(jù)加載中……

    Debugging with GDB (入門篇)

    Debug 是大家常常用到的東西.不管是自己寫程式也好,還是想改改別人寫好的東西, 又或者幫人家捉捉蟲(chóng).總之呢,絕對(duì)是個(gè)常常用的到的東西.Dos, windows 底下,通常大家都在用 softice. 這里我就不介紹了,因?yàn)樵谇懊娴?"學(xué)習(xí)程式"中的"Assembly"里面已經(jīng)有了很詳細(xì)的介紹了.這里我來(lái)說(shuō)說(shuō) linux 底下的 GDB 吧.

    GDB 的全稱是 GNU Debuger. 是 linux 底下的一種免費(fèi)的 debug 程式.隨然介面不像 SoftIce 那麼好,但是功能也絕對(duì)強(qiáng)大.要使用 gdb 那麼首先,在你 compile 程式的時(shí)候, 要加上 -g 的選項(xiàng). (可以用-g, -g2, -g3具體請(qǐng)看 man gcc)通常如果程式不會(huì)很大,在 compile 的時(shí)候我都是用 -g3 的,因?yàn)槿绻阌玫搅?inline 的 function, 用 -g 去 compile 就無(wú)法去 debug inline function了.這時(shí)候就用到 -g2, -g3了,g後面的數(shù)字越大,也就是說(shuō)可以 debug 的級(jí)別越高.最高級(jí)別就是 -g3.

    既然是入門篇,就從最簡(jiǎn)單的來(lái)做啦.先寫個(gè)小程式,我們用來(lái)學(xué)習(xí) gdb. 用你喜愛(ài)的 editor 編輯一個(gè)叫做 test.c 的文件,內(nèi)容如下∶

    int main()
    {
    	int a, b, c;
    	a=5;
    	b=10;
    	b+=a;
    	c=b+a;
    	return 0;
    }
    
    然後用下面的指令去編輯這個(gè)程式∶
    
    gcc -Wall -g -o test test.c
    
    這樣 gcc 就會(huì) compile 一個(gè)叫做 test 的小程式.現(xiàn)在我們來(lái)用 gdb 看看這個(gè)小程式∶
    
    gdb -q test
    
    (gdb) l			(這里用 l 指令,是 list 的簡(jiǎn)寫)
    
    1       int main()
    2       {
    3               int a, b, c;
    4               a=5;
    5               b=10;
    6               b+=a;
    7               c=b+a;
    8               return 0;
    9       }
    
    (這時(shí)候你就可以看到程式的 source 了)
    
    
    我們現(xiàn)在下一個(gè) breakpoint,這個(gè) breakpoint 將會(huì)在第二行,也就是 2 { 這里.
    這樣程式運(yùn)行完 int main()以後,就會(huì)停下來(lái).
    
    (gdb) b 2	(b 就是 breakpoint 的簡(jiǎn)寫啦)
    Breakpoint 1 at 0x80483a0: file test.c, line 2. 
    
    現(xiàn)在來(lái)運(yùn)行這個(gè)程式
    
    (gdb) r		(r是 run 的簡(jiǎn)寫)
    Starting program: /home/goldencat/study-area/goldencat/gdb/test 
    
    Breakpoint 1, main () at test.c:2
    2       {
    程式運(yùn)行到這里,就停下來(lái)了.因?yàn)槲覀冊(cè)谶@里設(shè)下了 breakpoint.
    (gdb)n		(n = next)
    main () at test.c:4
    4               a=5; (這里就跑到了第四行了)
    (gdb) n
    5               b=10;
    (gdb) n
    6               b+=a;
    (gdb) n
    7               c=b+a;
    這時(shí)候我們來(lái)看看 b 的 value 是多少∶
    
    (gdb) p b	(p是print的簡(jiǎn)寫,這里實(shí)際寫成print b)
    $1 = 15		(這里顯示的就是 b 的 value, 以後要看 b, 直接用 p $1 也是一樣的)
    		(這里的 $1 就是指向 b 的)
    
    (gdb) n
    8               return 0;
    (gdb) p c
    $2 = 20		(這里看到 c 的 value 是 20)
    (gdb) c		(c 是 continue 的意思,也就是說(shuō)執(zhí)行到程式的結(jié)束)
    Continuing.
    
    Program exited normally.
    (gdb) q		(這就結(jié)束 gdb 了 )
    
    跟 n (next) 不同的,還有一個(gè)用法就是 step. step 很有用的就是,當(dāng)你追到一個(gè)call 的時(shí)候,(如 my_function(value1))如果用 next 會(huì)只接跑過(guò)這個(gè) call,而不會(huì)跑到這個(gè) call里面, step 就不同了. step 會(huì)跑到這個(gè) call 的里面去,讓你能追到 call 里面.

    這里在順便說(shuō)說(shuō)如何改變一個(gè) value. 當(dāng)你下指令 p 的時(shí)候,例如你用 p b, 這時(shí)候你會(huì)看到 b 的 value, 也就是上面的 $1 = 15. 你也同樣可以用 p 來(lái)改變一個(gè) value, 例如下指令 p b = 100 試試看,這時(shí)候你會(huì)發(fā)現(xiàn), b 的 value 就變成 100 了∶$1 = 100.

    利用display這個(gè)命令,你可以在每一次的 next 時(shí),都顯示其中一個(gè)的 value,看看下面的范例也許容易明白些∶

    [goldencat@goldencat gdb]$ gdb -q test
    (gdb) l 
    1       int main()
    2       {
    3               int a, b, c;
    4               a=5;
    5               b=10;
    6               b+=a;
    7               c=b+a;
    8               return 0;
    9       }
    (gdb) b 2
    Breakpoint 1 at 0x80483a0: file test.c, line 2.
    (gdb) r
    Starting program: /home/goldencat/study-area/goldencat/gdb/test 
    
    Breakpoint 1, main () at test.c:2
    2       {
    (gdb) n
    main () at test.c:4
    4               a=5;
    (gdb) display a		(set display on)
    1: a = 134517840
    (gdb) n
    5               b=10;
    1: a = 5		(display a)
    (gdb) n
    6               b+=a;
    1: a = 5		(display a)
    (gdb) n
    7               c=b+a;
    1: a = 5		(display a)
    (gdb) n
    8               return 0;
    1: a = 5		(display a)
    (gdb) c
    Continuing.
    
    Program exited normally.
    (gdb) q
    
    當(dāng)然你要 display 多少個(gè) value 并沒(méi)有甚麼限制.你完全可以把 a, b, c全部都display出來(lái). 利用 info 這個(gè)指令,你可以看到目前的狀況.如∶ info display 就能看到目前的display 的狀況∶

    (gdb) info display
    Auto-display expressions now in effect:
    Num Enb Expression
    1:   y  b	(這里的 y 就是說(shuō), display b 是 enable 的)
    
    用 info break 就可以看到 breakpoint 的狀況∶
    
    (gdb) info break
    Num Type           Disp Enb Address    What
    1   breakpoint     keep y   0x080483a0 in main at test.c:2
            breakpoint already hit 1 time
    (gdb) 
    
    	利用 disable 和 enable 命令,可以贊時(shí)開(kāi)啟和這關(guān)閉一些命令.例如∶
    
    (gdb) disable display 1
    (gdb) info display
    Auto-display expressions now in effect:
    Num Enb Expression
    1:   n  b		(這里看到個(gè) n, 也就是說(shuō), display b 已經(jīng)被關(guān)閉了)
    (gdb) 			
    
    
    (gdb) disable break 1
    (gdb) info break
    Num Type           Disp Enb Address    What
    1   breakpoint     keep n   0x080483a0 in main at test.c:2
            breakpoint already hit 1 time
    (gdb) 		(這里看到,breakpoint也被用 disable break 1 給關(guān)閉了)
    
    如果你問(wèn)我為甚麼要用 1 (disable break/display 1),看看上面的 Num 那幾個(gè)字就知道了. 這里的 1 就是說(shuō)關(guān)閉第一個(gè) value. 因?yàn)楫?dāng)你真正 debug 的是侯,可能有很多的 break,你只要關(guān)閉你想要關(guān)閉的就好了,看看下面∶

    (gdb) info display
    Auto-display expressions now in effect:
    Num Enb Expression
    3:   y  c
    2:   y  b
    1:   y  a
    
    這里 display 中有三個(gè) value, 現(xiàn)在我想贊時(shí)關(guān)閉對(duì) b 的 display,可以從 Num 看出, b 的 Num 是 2,所以我們要用 disable display 2

    (gdb) disable display 2
    (gdb) info display
    Auto-display expressions now in effect:
    Num Enb Expression
    3:   y  c
    2:   n  b		(這里看到, b 已經(jīng)關(guān)閉了)
    1:   y  a
    
    如果你用 disable display 而後面沒(méi)有任何的 number 的話,那麼就是 disable all 的意思∶

    (gdb) disable display  
    (gdb) info display
    Auto-display expressions now in effect:
    Num Enb Expression
    3:   n  c
    2:   n  b
    1:   n  a
    (gdb) 
    
    接下來(lái)說(shuō)說(shuō) enable 吧, 知道了 disable, enable 就簡(jiǎn)單多了. enable 就是跟 disable 相反的意思.也就是說(shuō)重新開(kāi)啟被關(guān)閉的東西.用法跟 disable 一樣.

    (gdb) enable display 2
    (gdb) info display
    Auto-display expressions now in effect:
    Num Enb Expression
    3:   n  c
    2:   y  b
    1:   n  a
    (gdb) enable display
    (gdb) info display
    Auto-display expressions now in effect:
    Num Enb Expression
    3:   y  c
    2:   y  b
    1:   y  a
    (gdb) 
    
    再來(lái)講講 delete 的用法啦. delete 跟 disable 不太一樣,一旦被 delete, 那麼是沒(méi)有辦法用 enable 之類的東西找回來(lái)的.假設(shè)你 disable 一個(gè) breakpoint,那麼就是說(shuō),你贊時(shí)不需要用到這個(gè) break point,當(dāng)你要用到的時(shí)候,只要 enable 就好.可是如果你去 delete 一個(gè) breakpoint.就是說(shuō)你將用遠(yuǎn)不需要這個(gè) breakpoint 了.如果你下次還需要, 那麼你就給重新用 break 指令去下 breakpoint 了.

    (gdb) delete display 1
    (gdb) info display
    Auto-display expressions now in effect:
    Num Enb Expression
    3:   y  c
    2:   y  b		(1 消失了)
    (gdb) delete display	(全部 delete )
    Delete all auto-display expressions? (y or n) y		(要求確定一下)
    (gdb) info display
    There are no auto-display expressions now.	(全部的 display 都被 delete 了)
    (gdb) 
    
    順便說(shuō)說(shuō)如何去 debug 一個(gè)已經(jīng)在 run 的程式∶
    利用 attach process-id 和 detach 就可以去 debug 一個(gè)已經(jīng)在 run 的程式了.

    先用 ps aux 找出你要 debug 的程式的 process it.
    
    [goldencat@goldencat gdb]$ ps aux | grep ssh
    root       600  0.0  0.0  2248    0 ?        SW   11:13   0:00 [sshd]
    goldenca  1182  0.0  0.7  2448  188 tty2     S    11:40   0:00 ssh 127.0.0.1
    goldenca  2802  0.0  1.9  1904  528 pts/1    S    13:45   0:00 grep ssh
    
    這里我們?nèi)?debug ssh 127.0.0.1 這個(gè)程式,這這程式的 process id 是 1182
    
    [root@goldencat /root]# gdb -q		進(jìn)入gdb
    
    (gdb) attach 1182			截入 process 1182 到 gdb 里面
    Attaching to Pid 1182
    0x401b615e in ?? ()
    ......
    ......
    ......					進(jìn)行 debug
    ......
    ......
    
    (gdb) detach				debug 完畢以後,記得要用 detach 這個(gè)命令
    Detaching from program: , Pid 1182	這個(gè)命令就把剛剛 debug 的那個(gè)程式 release
    (gdb) q					掉了.
    

    好啦,入門篇嘛,就寫這麼多了.我寫的慢,這些就寫了我一個(gè)早上啦.不敢說(shuō)能教了大家甚麼東西,但也算是給沒(méi)有玩過(guò)的人一個(gè)入門的概念啦.簡(jiǎn)單的,常用到的break,print, display,disable,enable,delete,run,next,step,continue好像也都說(shuō)到了. 如果你有心想學(xué),可以看看 man gdb 和進(jìn)入 gdb 後,用 help 指令. GDB 里面的 help 是很好用的.

    如果你是個(gè) debug 的高手,那麼希望你也能抽點(diǎn)時(shí)間,跟大家分享一下你的心得.獨(dú)樂(lè)樂(lè)不如眾樂(lè)樂(lè)嘛. ∶)

    下面是個(gè)如何使用 gdb 中的 help 的范例∶
    
    
    [goldencat@goldencat gdb]$ gdb -q
    (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) help breakpoints
    Making program stop at certain points.
    
    List of commands:
    
    awatch -- Set a watchpoint for an expression
    break -- Set breakpoint at specified line or function
    catch -- Set catchpoints to catch events
    clear -- Clear breakpoint at specified line or function
    commands -- Set commands to be executed when a breakpoint is hit
    condition -- Specify breakpoint number N to break only if COND is true
    delete -- Delete some breakpoints or auto-display expressions
    disable -- Disable some breakpoints
    enable -- Enable some breakpoints
    hbreak -- Set a hardware assisted  breakpoint
    ignore -- Set ignore-count of breakpoint number N to COUNT
    rbreak -- Set a breakpoint for all functions matching REGEXP
    rwatch -- Set a read watchpoint for an expression
    tbreak -- Set a temporary breakpoint
    tcatch -- Set temporary catchpoints to catch events
    thbreak -- Set a temporary hardware assisted breakpoint
    txbreak -- Set temporary breakpoint at procedure exit
    watch -- Set a watchpoint for an expression
    xbreak -- Set breakpoint at procedure exit
    
    Type "help" followed by command name for full documentation.
    Command name abbreviations are allowed if unambiguous.
    (gdb) help clear
    Clear breakpoint at specified line or function.
    Argument may be line number, function name, or "*" and an address.
    If line number is specified, all breakpoints in that line are cleared.
    If function is specified, breakpoints at beginning of function are cleared.
    If an address is specified, breakpoints at that address are cleared.
    
    With no argument, clears all breakpoints in the line that the selected frame
    is executing in.
    
    See also the "delete" command which clears breakpoints by number.
    (gdb) q

    from: http://blog.chinaunix.net/u/9483/showart.php?id=57476

    posted on 2006-07-30 23:45 weidagang2046 閱讀(3832) 評(píng)論(1)  編輯  收藏 所屬分類: Linux

    評(píng)論

    # re: Debugging with GDB (入門篇)  回復(fù)  更多評(píng)論   

    hao,taihao le
    2008-03-09 19:43 | sunlight
    主站蜘蛛池模板: 任你躁在线精品免费| 狠狠色婷婷狠狠狠亚洲综合 | 亚洲欧洲美洲无码精品VA| jizz在线免费播放| 亚洲午夜精品一级在线播放放 | 久久国产亚洲精品| 在线观看免费人成视频色9| 亚洲综合色7777情网站777| 三年片在线观看免费观看高清电影| 亚洲激情视频网站| 91精品国产免费久久久久久青草 | 一级毛片**免费看试看20分钟| 亚洲国产一成久久精品国产成人综合 | 亚洲综合无码一区二区痴汉 | 亚洲AV电影院在线观看| 99热这里只有精品6免费| 亚洲精品无码久久久久久久| 国产成人精品免费视频大| 色噜噜亚洲男人的天堂| 色吊丝永久在线观看最新免费| 亚洲av无码一区二区三区四区| 四虎国产精品免费视| 一级毛片免费播放试看60分钟| 国产亚洲大尺度无码无码专线| 国产一精品一AV一免费| 久久精品国产亚洲av高清漫画| 综合在线免费视频| 亚洲国产精品无码久久| 日产国产精品亚洲系列| 美女巨胸喷奶水视频www免费| 久久精品国产亚洲AV麻豆不卡 | 亚洲国产综合人成综合网站| 抽搐一进一出gif免费视频| 久久久久亚洲精品美女| 成年人视频免费在线观看| 亚洲videos| 国产一精品一aⅴ一免费| 久久国产福利免费| 亚洲美女视频免费| 麻豆精品国产免费观看| jizz免费观看视频|