標籤:index control poi processor warning 使用 table 資料 set
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 execCatchpoint 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:8720No symbol table is loaded. Use the "file" command.(gdb) cContinuing(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:8720Breakpoint 2 at 0x15f9694: file lib.cc, line 8720.(gdb) cContinuing.[Thread debugging using libthread_db enabled][Thread 0x40861940 (LWP 12602) exited][Switching to process 12630]0x0000003c6980d81c in vfork () from /lib64/libpthread.so.0Warning: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) cContinuing.[New process 12630]Executing new program: /****/binarywarning: 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:8720Breakpoint 4 at 0x15f9694: file lib.cc, line 8720.(gdb) b type.cc:32Breakpoint 5 at 0x1693050: file type.cc, line 32.(gdb) cContinuing.(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。不清楚。
Gdb調試多進程程式