天天看點

Gdb調試多程序程式

Gdb調試多程序程式

程式經常使用fork/exec建立多程序程式。多程序程式有自己獨立的位址空間,這是多程序調試首要注意的地方。Gdb功能強大,對調試多線程提供很多支援。

方法1:調試多程序最土的辦法:attach pid

Attach是調試程序的常用辦法,隻要有可執行程式以及相應PID,即可工作。當然,為友善調試,可以在程序啟動後,設定sleep一段時間,如30s,這樣即可有充足的時間來attach。

方法2: set follow-fork-mode child + main斷點

當設定set follow-fork-mode child,gdb将在fork之後直接執行子程序,知道碰到斷點後停止。如何設定子程序的斷點呢?在父程序中是無法知道子程序的位址空間的(隻有等程式載入後方可知)。Gdb提供一個很友善的機制:main函數的斷點将被子程序繼承(畢竟main是任何程式的入口)。

注意:程式在main停下後,可嘗試設定斷點。斷點是否有效,取決于gdb是否已經載入目标程式的位址空間。

方法3: set follow-fork-mode child + catch exec

Cache點是一種特殊的breakpoint。Gdb能夠catch的事件很多,如

throw/catch/exception/syscall/exec/fork/vfork

等。其中和多程序關系最大的就是

exec/fork

事件。

舉例:

GNU gdb Fedora (6.8-27.el5)

Copyright (C) 2008 Free Software Foundation, Inc.

(gdb)

catch

exec

Catchpoint 1 (exec)

(gdb) set follow-fork-mode child

(gdb) r  -d ***

Catchpoint 1 (exec'd

/****/

binary), 0x0000003c68800a70 in _start ()

from /lib64/ld-linux-x86-64.so.2

(gdb) bt

#0  0x0000003c68800a70 in _start () from /lib64/ld-linux-x86-64.so.2

#1  0x0000000000000003 in ?? ()

#2  0x00007fff65c6e85a in ?? ()

#3  0x00007fff65c6e85d in ?? ()

#4  0x00007fff65c6e860 in ?? ()

(gdb) b lib.cc:8720

No symbol table is loaded.  Use the

"file"

command.

(gdb) c

Continuing

(gdb) bt

#0  0x0000003c68800a70 in _start () from /lib64/ld-linux-x86-64.so.2

#1  0x0000000000000002 in ?? ()

#2  0x00007fff1af7682a in ?? ()

#3  0x0000000000000000 in ?? ()

(gdb)  b lib.cc:8720

Breakpoint 2 at 0x15f9694: file lib.cc, line 8720.

(gdb) c

Continuing.

[Thread debugging

using

libthread_db enabled]

[Thread 0x40861940 (LWP 12602) exited]

[Switching to process 12630]

0x0000003c6980d81c in vfork () from /lib64/libpthread.so.0

Warning:

Cannot insert breakpoint 2.

Error accessing memory address 0x15f9694: Input/output error.

(gdb) bt

#0  0x0000003c6980d81c in vfork () from /lib64/libpthread.so.0

#1  0x000000000040c3fb in ?? ()

#2  0x00002adeab604000 in ?? ()

#3  0x01000000004051ef in ?? ()

#4  0x00007fffff4a42f0 in ?? ()

#5  0x686365746e6f6972 in ?? ()

#6  0x0000000d0000000c in ?? ()

#7  0x0000000b0000000a in ?? ()

#8  0x0000000000000000 in ?? ()

(gdb)

delete

2  --此處當breakpoint無效時,必須删除,否則程式無法繼續

(gdb) c

Continuing.

[New process 12630]

Executing

new

program:

/****/

binary

warning: Cannot initialize

thread

debugging library: generic error

[Switching to process 12630]

Catchpoint 1 (exec'd

/****/

binary), 0x0000003c68800a70 in _start ()

from /lib64/ld-linux-x86-64.so.2

(gdb) bt

#0  0x0000003c68800a70 in _start () from /lib64/ld-linux-x86-64.so.2

#1  0x0000000000000009 in ?? ()

Backtrace stopped: previous frame inner to

this

frame (corrupt stack?)

(gdb) b lib.cc:8720

Breakpoint 4 at 0x15f9694: file lib.cc, line 8720.

(gdb) b type.cc:32

Breakpoint 5 at 0x1693050: file type.cc, line 32.

(gdb) c

Continuing.

(gdb)  -- 和正常程式調試一樣

說明:

catch exec

後,程式将在

fork/vfork/exec

處停下。并非每次停下後,設定斷點都是有效的。如提供斷點無效,需要删除,否則程式無法繼續。要能夠在新程序中設定斷點,一定要等到新程序的位址空間被載入後,設定斷點是才有效

(exec

将改變原程式的位址空間

)

。上述例子,主要想展示如何對新程序設定斷點!

注意:

1)

程式位址非常重要

(

代碼和資料位址一樣重要

)

。使用

gdb

時,多多注意和利用位址資訊。

2)

On some systems, when a child process is spawned by vfork, you cannot debug the child or parent until an exec call completes.

方法

4

info inferiors/inferiors inferiors

設定

set detach-on-fork off/set follow-exec-mode new

If you choose to set `detach-on-fork' mode off, then gdb will retain control of all forked processes (including nested forks). You can list the forked processes under the control of gdb by using the 

info inferiors

 command, and switch from one fork to another by using the 

inferior

 command.

所使用的gdb不支援

set detach-on-fork off/set follow-exec-mode new/info inferiors

。不清楚。

參考

4.11 Debugging Forks

作者:

zhenjing.chen

出處:

http://www.cnblogs.com/zhenjing/

未注明轉載的文章,版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。