主頁 > 移動端開發 > 軟體除錯的藝術筆記:GDB

軟體除錯的藝術筆記:GDB

2020-10-20 19:09:25 移動端開發

很久之前,在https://blog.csdn.net/fengbingchun/article/details/41413381中簡單整理過gdb中常用的一些命令,不齊全,這里按照《軟體除錯的藝術》一書中關于gdb的介紹再做次整理,《軟體除錯的藝術》于2009年由人民郵電出版社出版,

1. 預備知識

GDB:Unix程式員最常用的除錯工具,是由Richard Stallman開發的GNU專案除錯器(GNU Project Debugger),

DDD:Data Display Debugger,資料顯示除錯器,GDB的GUI(圖形用戶界面)前端:用戶通過GUI發出命令,GUI將這些命令傳遞給GDB,

Eclipse:IDE(集成開發環境),

GDB的命令允許在不產生歧義的情況下使用縮寫

從版本6.1以來,GDB已經以名為TUI(Terminal User Interface, 終端用戶界面)的模式提供了基于文本互動和圖形用戶互動之間的折中方法,在這一模式中,GDB將終端螢屏劃分為類似于DDD的源文本視窗和控制臺的多個子視窗:可以在類似于源文本視窗的子視窗中跟蹤程式執行的進展程序,同時在類似于控制臺的子視窗中發出GDB命令,也可以使用另一個程式CGDB,該程式也提供了類似的功能,

為了以TUI模式運行GDB,可以在呼叫GDB時在命令列上指定-tui選型,如gdb -tui main,或者處于非TUI模式時在GDB中使用Ctrl+X+A組合鍵,如果當前處于TUI模式,后一種命令方式就會使你離開TUI模式,TUI模式中,GDB視窗劃分為兩個子視窗:一個用于輸入GDB命令,而另一個用于查看源代碼,需要注意的是,在一些情況下TUI可能不能按照用戶所需要的方式運作,

1.5 主要除錯器操作

單步除錯源代碼:

(1).斷點:除錯工具會在指定斷點處暫停程式的執行,在GDB中是通過break命令及其行號完成的,

(2).單步除錯:GDB的next命令讓GDB執行下一行,然后暫停,step命令的作用與此類似,只是在函式呼叫時step命令會進入函式,而next導致程式執行的暫停出現在下次呼叫函式時,

(3).恢復操作:在GDB中,continue命令通知除錯器恢復執行并繼續,直到遇到斷點為止,

(4).臨時斷點:在GDB中,tbreak命令與break相似,但是這一命令設定的斷點的有效期限只到首次到達指定行時為止,GDB中還有創建特殊型別的一次性斷點的命令until和finish,

檢查變數:當除錯器暫停了程式的執行后,可以執行一些命令來顯示程式變數的值,這些變數可以是區域變數、全域變數、陣列的元素和C語言的struct、C++類中的成員變數等,如果發現某個變數有一個出乎意料的值,那往往是找出某個程式錯誤的位置和性質的重要線索,最基本的變數顯示型別是僅僅輸出當前值,在GDB中使用print命令輸出當前值,如查看變數j的當前值執行”(gdb) print j”,

設定監視點以應對變數值的改變:監視點結合了斷點和變數檢查的概念,最基本形式的監視點通知除錯器,每當指定變數的值發生變化時都暫停程式的執行,例如,在程式執行期間,假設要在變數z改變值時查看程式的狀態,在GDB中,可以執行如下命令:”(gdb) watch z”,當運行程式時,每當z的值發生變化,GDB都會暫停執行,更好的方法是,可以基于條件運算式來設定監視點,例如,假設要查找程式執行期間z的值大于28的第一個位置,在GDB中,輸入”(gdb) watch (z>28)”,監視點對區域變數的用途一般沒有對作用域更寬的變數的用途大,因為一旦變數超出作用域(即當在其中定義變數的函式結束時),在區域變數上設定的監視點就會被取消,

上下移動呼叫堆疊:在函式呼叫期間,與呼叫關聯的運行時資訊存盤在稱為堆疊幀(stack frame)的記憶體區域中,幀中包含函式的區域變數的值、其形參,以及呼叫該函式的位置的記錄,每次發生函式呼叫時,都會創建一個新幀,并將其推到一個系統維護的堆疊上;堆疊最上方的幀表示當前正在執行的函式,當函式退出時,這個幀被彈出堆疊,并且被釋放,在GDB中可用用如下命令查看以前的幀:“(gdb) frame 1”,當執行GDB的frame命令時,當前正在執行的函式的幀被編號為0,其父幀(即該函式的呼叫者的堆疊幀)被編號為1,父幀的父幀被編號為2,以此類推,GDB的up命令將你帶到呼叫堆疊中的下一個父幀(例如,從幀0到幀1),down則引向相反反向,這樣的操作非常有用,因為根據以前的一部分堆疊幀中的區域變數的值,可能發現一些關于引起程式錯誤的代碼的線索,遍歷呼叫堆疊不會修改執行路徑,但是它確實允許查看幀的祖先幀,因此可以檢查通向當前幀的函式呼叫的區域變數的值,GDB的backtrace命令會顯示整個堆疊,即當前存在的所有幀的集合

在GDB中,可以通過help命令訪問檔案,例如,”(gdb) help breakpoints”,將顯示關于斷點的檔案,不帶引數的GDB命令help提供了一個可用來作為help的引數的命令類別的選單,

1.7 初涉除錯會話:

注意,GCC中可以用-g選項讓編譯器將符號表(即對應于程式的變數和代碼行的記憶體地址串列)保存在生成的可執行檔案中,這是一個絕對必要的步驟,這樣才能在除錯會話程序中參考源代碼中的變數名和行號

與接受行號(或函式名)的break命令不同,condition接受斷點號,總是可以用命令info break來查詢要查找的斷點的編號,用break if可以將break和condition命令組合成一個步驟,如下所示”(gdb) break 30 if num_y==1”,然后用run命令再次運行程式,如果要重用老的命令列引數,就不必再次指定命令列引數,可以簡單地輸入run

我們在重新編譯程式之前仍然不必退出GDB,這樣做提供了很大的方便,第一,不需要重新指出命令列引數,只要鍵入run重新運行程式即可,其次,GDB保留了你設定的斷點,因此不需要再次鍵入它,同樣,在除錯會話期間不要退出再重啟文本編輯器,這件事也會分心而且浪費時間,只要將文本編輯器放在一個視窗中,GDB放在另一個視窗中,用第三個視窗除錯程式即可,

當運行程式試圖訪問不允許訪問的記憶體時發生了段錯誤,原因通常是由于陣列索引超出了邊界,或者采用了錯誤的指標值,段錯誤也可能由每月顯式地包含指標或陣列變數的記憶體參考產生,

1.8 啟動檔案的使用:

在重新編譯代碼時,最好不要退出GDB,這樣,你的斷點和建立的其它各種動作都會保留,要是退出GDB,就不得不再次重復鍵入所有這些內容為了不丟失它們,可以將斷點和設定的其它命令放在一個GDB啟動檔案中,然后每次啟動GDB時會自動加載它們

GDB的啟動檔案默認名為.gdbinit,可以將一個檔案放在主目錄中用于一般用途,另一個檔案放在包含該專案特有用途的特定專案的目錄中,GDB在加載可執行檔案之前會讀取主目錄中的啟動檔案,在呼叫GDB時可以指定啟動檔案,例如”$ gdb -command=z x”,表示要在可執行檔案x上運行GDB,首先要從檔案z中讀取命令,

2. 停下來環顧程式

2.1 暫停機制:有3種方式可以通知GDB暫停程式的執行:

(1).斷點:通知GDB在程式中的特定位置暫停執行,

(2).監視點:通知GDB當特定記憶體位置(或者涉及一個或多個位置的運算式)的值發生變化時暫停執行,

(3).捕獲點:通知GDB當特定事件發生時暫停執行,

2.2 斷點概述:在程式中的特定”位置”設定斷點,當到達那一點時,除錯器會暫停程式的執行(在GDB這樣的基于文本的除錯器的情況下,會出現命令列提示符),GDB中關于”位置”的含義是非常靈活的,它可以指各種源代碼行、代碼地址、源代碼檔案中的行號或者函式的入口等,

GDB命令列提示符上面顯式的陳述句資訊是將要執行的代碼行,而不是GDB最后執行的代碼行,如下圖所示,接下來將要執行的是Messy_Test.cpp的第6行,GDB的作業針對的是機器語言指令,而不是源代碼行,一行代碼可能對應于數行機器語言,GDB之所以可以使用源代碼,是因為可執行檔案中包含了額外的資訊,

2.3 跟蹤斷點:程式員創建的每個斷點(包括斷點、監視點和捕獲點)都被標識為從1開始的唯一整數識別符號,這個識別符號用來執行該斷點上的各種操作,除錯器還包括一種列出所有斷點及其屬性的方式,當創建斷點時,GDB會告知你分配給該斷點的編號,如果忘記了分配給哪個斷點的編號是什么,可以使用”(gdb) info breakpoints”命令來提示,通過使用delete命令以及斷點識別符號,可以洗掉斷點、監視點及捕獲點,

2.4 設定斷點:GDB中有許多指定斷點的方式,下面是一些最常見的方法:

(1).break funciton:在函式function的入口(第一行可執行代碼)處設定斷點,

(2).break line_number:在當前活動源代碼檔案的line_number處設定斷點

(3).break filename:line_number:在源代碼檔案filename的line_number處設定斷點,如果filename不在當前作業目錄中,則可以給出相對路徑名或者完全路徑名來幫助GDB查找該檔案

(4).break filename:function:在檔案filename中的函式function的入口處設定斷點,多載函式或者使用同名靜態函式的程式可能需要使用這種形式,

當設定一個斷點時,該斷點的有效性會持續到洗掉、禁用或退出GDB時,然而,臨時斷點是首次到達后就會被自動洗掉的斷點,臨時斷點使用tbreak命令設定,它與break采用相同型別的引數GDB實際設定斷點的位置可能與請求將斷點放置的位置不同,當打開優化來編譯程式時,這個問題可能變得更糟糕,GDB最終使用的是機器指令,在除錯完成前不應當優化代碼,

當GDB使用多個斷點中斷一行源代碼時,它只會中斷一次,換言之,當它到達該行代碼時,如果恢復執行,會忽略恰好在同一行上的其它斷點,事實上,GDB知道是哪個斷點”觸發”了程式停止執行,在具有多個斷點的代碼行上,觸發中斷的斷點將是識別符號編號最小的斷點,

2.5 展開GDB示例:

啟動除錯會話時在main()中設定斷點是非常普遍的,這一操作在該函式的第一行上設定斷點:”(gdb) break main”,

在任何給定時間,GDB都有一個焦點,可以將它看作當前”活動”檔案,這意味著除非對命令做了限定,否則都是在具有GDB的焦點的檔案上執行命令,默認情況下,具有GDB的初始焦點的檔案是包含main()函式的檔案,但是當發生如下任一動作時,焦點會轉移到不同的檔案上:

(1).向不同的源檔案應用list命令,

(2).進入位于不同的源代碼檔案中的代碼,

(3).當在不同的源代碼檔案中執行代碼時GDB遇到斷點,

使用quit命令離開GDB,

2.6 斷點的持久性:如果在修改和重新編譯代碼時沒有退出GDB,那么在下次執行GDB的run命令時,GDB會感知到代碼已修改,并自動重新加載新版本,然而要注意,斷點是會”移動”的,

2.7 洗掉和禁用斷點:這里提到的一切方法都同樣適用于監視點,

GDB中有兩個用來洗掉斷點的命令:delete和clear,delete命令用來基于識別符號洗掉斷點,clear命令使用與創建斷點相同的語法洗掉斷點,

(1).delete breakpoint_list:洗掉斷點使用數值識別符號,斷點可以是一個數字,比如delete 2洗掉第二個斷點;也可以是數字串列,比如delete 2 4洗掉第二個和第四個斷點,

(2).delete:洗掉所有斷點,

(3).clear:清除GDB將執行的下一個指令處的斷點,這種方法適用于要洗掉GDB已經到達的斷點的情況

(4).clear function、clear filename:funciton、clear line_number和clear filename:line_number:這些命令根據位置清除斷點,作業方式與對應的break命令相似,

每個斷點都可以被啟用或禁用,只有當GDB遇到啟用的斷點時,才會暫停程式的執行;它會忽略禁用的斷點,默認情況下,斷點的生命期從啟用時開始,在除錯會話期間,會遇到大量斷點,對于經常重復的回圈結構或函式,這種情況使得除錯極不方便,如果要保留斷點以便以后使用,暫時又不希望GDB停止執行,可以禁用它們,在以后需要時再啟用,

使用disable breakpoint-list命令禁用斷點,使用enable breakpoint-list命令啟用斷點,其中breakpoint-list是使用空格分隔的串列,其中有一個或多個斷點識別符號,不帶任何引數地執行disable命令將禁用所有現有斷點,類似地,不帶引數地執行enable命令會啟用所有現有斷點,還有一個enable once命令”enable once breakpoint-list”,在斷點下次引起GDB暫停執行后被禁用,這個命令與tbreak命令非常類似,但是當遇到斷點時,它是禁用斷點,而不是洗掉斷點,

2.8 進一步介紹瀏覽斷點屬性:每個斷點都有各種屬性----行號、加在斷點上的條件(如果有的話)、當前啟用/禁用狀態等,

創建的每個斷點都被賦予了唯一的整數識別符號,設定的第一個斷點被賦予”1”,其后的每個斷點都被賦予所賦的上一個識別符號加1.每個斷點也有一些控制調整其行為的屬性,使用唯一識別符號,可以分別調整各個斷點的屬性,可以使用”(gdb) info breakpoints”命令(簡寫為”i b”)來獲得設定的所有斷點的清單,以及它們的屬性,info breakpoints的輸出看上去或多或少類似于如下所示:

(1).識別符號(Num):斷點的唯一識別符號,

(2).型別(Type):這個欄位指出該斷點是斷點、監視點還是捕獲點,

(3).部署(Disp):每個斷點都有一個部署,指示斷點下次引起GDB暫停程式的執行后該斷點上會發生什么事情,可能的部署有3種:

a.保持(keep):下次到達斷點后不改變斷點,這是新建斷點的默認部署,

b.洗掉(del):下次到達斷點后洗掉該斷點,使用tbreak命令創建的任何斷點都是這樣的斷點,

c.禁用(dis):下次到達斷點時會禁用該斷點,這是使用enable once命令設定的斷點,

(4).啟用狀態(Enb):這個欄位說明斷點當前是啟用還是禁用的,

(5).地址(Address):這是記憶體中設定斷點的位置,它主要用于匯編語言程式員,或者試圖除錯沒有用擴充的符號表編譯的可執行檔案的人,

(6).位置(What):各個斷點位于源代碼中的特定行上,What欄位顯示了斷點所在位置的行號和檔案號,

2.9 恢復執行:方法有3類:

(1).使用step和next”單步”除錯程式,僅執行代碼的下一行然后再次暫停,一旦GDB在斷點處停止,可以使用next(簡寫為n)和step(簡寫為s)命令來單步除錯代碼,當觸發了斷點,并且GDB暫停后,可以使用next和step來執行緊接著的下一行代碼,當執行了這一行后,GDB會再次暫停,并給出一個命令列提示符,這兩個命令的區別是它們如何處理函式呼叫:next執行函式,不會在其中暫停,然后在呼叫之后的第一條陳述句處暫停,step在函式中的第一個陳述句處暫停,next將函式呼叫看作一行代碼,并在一個操作中執行整個函式,這稱為單步越過(stepping over)函式,next和step命令都采用一個可選的數值引數,表示要使用next或step執行的額外行數,換言之,next 3與在一行中鍵入next三次(或者鍵入next一次,然后按下ENTER鍵兩次)的作用相同,如果是在沒有函式呼叫的那部分代碼中,那么使用next還是step并沒有關系,在這種情況下,兩個命令是完全相同的

(2).由使用continue組成,使GDB無條件地恢復程式的執行,直到它遇到另一個斷點或者程式結束,簡寫為c,與僅執行一行代碼的step和next相反,這個命令使GDB恢復程式的執行,直到觸發斷點或者程式結束,continue命令可以接受一個可選的整數引數n,這個數字要求GDB忽略下面n個斷點,

(3).涉及條件,用finish或until命令恢復,在這種情況下,GDB會恢復執行,程式繼續運行直到遇到某個預先確定的條件(比如,到達函式的末尾),到達另一個斷點,或者程式完成,

使用finish恢復程式執行:想回傳到單步進入被呼叫函式之前GDB所在的呼叫函式,這時應該使用finish命令finish命令(簡寫為fin)指示GDB恢復執行,直到恰好在當前堆疊幀完成之后為止,也就是說,這意味著如果你在一個不是main的函式中,finish命令會導致GDB恢復執行,直到恰好在函式回傳之后為止,finish的另一個常見用途是當不小心單步進入原本希望單步越過的函式時(換言之,當需要使用next時使用了step),在這種情況下,使用finish可以將你正好放回到使用next會位于的位置,

如果在一個遞回函式中,finish只會將你帶到遞回的上一層,這是因為每次呼叫都被看作在它自己權限內的函式呼叫,因為每個函式都有各自的堆疊幀,如果要在遞回層次較高時完全退出遞回函式,那么更適合使用臨時斷點及continue,或者用until命令,

使用until恢復程式執行:finish命令在不進一步在函式中暫停(除了中間斷點)的情況下完成當前函式的執行,類似地,until命令(簡寫為u)通常用來在不進一步在回圈中暫停(除了回圈中的中間斷點)的情況下完成正在執行的回圈,使用until會執行回圈的其余部分,讓GDB在回圈后面的第一行代碼處暫停,如果在回圈的末尾,執行until命令導致回跳到回圈頂部,這時只要再次執行until,就可以離開當前的回圈,until命令也可以接受源代碼中的位置作為引數,事實上,該命令接受的引數與break命令相同,

2.10 條件斷點:這類似于監視點的作業方式,但是有一個重要區別,如果懷疑某個變數得到了一個偽值,那么條件斷點相當適用于監視點,每當該變數的值發生變化時,監視點都會中斷,條件斷點只會在懷疑有問題的代碼處當變數呈現該懷疑值時才中斷,設定條件斷點的語法為”break break-args if (condition)”,其中break-args是可以傳遞給break以指定斷點位置的任何引數,condition是定義的布爾運算式,括著condition的圓括號是可選的,如”(gdb) break main if argc > 1”:說明了如果用戶向程式中鍵入一些命令列引數,則在main()處中斷,條件中斷極其有用,尤其適用于索引變數的特定值出了問題的回圈結構,條件中斷也極其靈活,不僅可以測驗相等或不相等的變數,在有效的C條件陳述句中幾乎可以使用任何運算式,無論使用什么運算式,都需要具有布林值,即真(非0)或假(0)

(1).相等、邏輯和不相等運算子(<、<=、==、!=、>、>=、&&、||等),如”(gdb) break 180 if string==nullptr && i < 0”

(2).按位和移位運算子(&、|、^、>>、<<等),如”(gdb) break test.c:34 if (x & y) == 1”

(3).算術運算子(+、-、*、/、%),如”(gdb) break myfunc if i % (j + 3) != 0”

(4).你自己的函式,只要它們被鏈接到程式中,如”(gdb) break test.c:myfunc if ! check_variable_sanity(i)”

(5).庫函式,只要該庫被鏈接到代碼中,例如:”(gdb) break 44 if strlen(mystring) == 0”

由于優先級的次序規則在起作用,因此可能需要使用圓括號將一些結構括起來,此外,如果在GDB運算式中使用庫函式,而該庫不是用除錯符號編譯的(幾乎肯定是這種情況),那么唯一能在斷點條件中使用的回傳值型別為int,換言之,如果沒有除錯資訊,GDB會假設函式的回傳值是int型別,當這種假設不正確時,函式的回傳值會被曲解,

可以對正常斷點設定條件以將它們轉變為條件斷點,例如,如果設定了斷點3作為無條件斷點,但是現在希望添加條件i==3,只要鍵入”(gdb) cond 3 i == 3”,如果以后要洗掉條件,但是保持該斷點,只要鍵入”(gdb) cond 3”,

2.11 斷點命令串列:使用”斷點命令串列”可以讓GDB在每次到達某個斷點時自動執行一組命令,從而自動完成反復查看相同的變數這一程序,使用commands命令設定命令串列,逐條輸入命令,然后鍵入end表示輸入命令完畢,從那以后,每當GDB在這個斷點處中斷時,它都會執行你輸入的任何命令,

可以使用GDB的define命令創建宏,可以將宏保存在.gdbinit檔案中,以便將它用于其它程式,鍵入”(gdb) show user”可以得到所有宏的串列,

2.12 監視點:是一種特殊型別的斷點,它類似于正常斷點,是要求GDB暫停程式執行的指令,區別在于監視點沒有”住在”某一行源代碼中,取而代之的是,監視點是指示GDB每當某個運算式改變了值就暫停執行的命令,如”(gdb) watch (i | j > 12) && i > 24 && strlen(name) > 6”,可以將監視點看作被”附加”在運算式上,當運算式的值改變時,GDB會暫停程式的執行,

雖然管理監視點和斷點的方式相同,但是兩者之間有一個重要區別,斷點與源代碼中的一個位置關聯,只要代碼沒有改變,就不存在某行代碼”超出作用域”的風險,因為C語言有嚴格的作用域規則,所以只能監視存在且在作用域內的變數,一旦變數不再存在于呼叫堆疊的任何幀中(當包含區域變數的函式回傳時),GDB會自動洗掉監視點,GDB只能監視單個執行緒中的變數

當變數var存在且在作用域中時,可以通過使用如下命令來設定監視點:”(gdb) watch var”,該命令會導致每當var改變值時GDB都中斷,GDB實際上是在var的記憶體位置改變值時中斷,監視點不僅僅限于監視變數,事實上,可以監視涉及變數的運算式,每當運算式修改值時,GDB都會中斷,

GDB中的運算式可以包含:

(1).GDB方便變數(convenience variables),

(2).程式中的任何在作用域內的變數,

(3).任何種類的字串、數值或字符常量,

(4).前處理器宏(如果程式被編譯為包括前處理器除錯資訊),

(5).條件、函式呼叫、型別強制轉換和所用語言定義的運算子,

3. 檢查和設定變數

3.2 變數的高級檢查和設定:

GDB的display命令(簡寫為disp)在執行中每次有暫停(由于有斷點,使用next或step命令等)時就輸出指定條目的值,只有當變數在作用域中時才生效,

在GDB中可以輸出整個陣列的值,如”(gdb) p x”或”(gdb) *pointer@number_of_elements”,

在GDB中,可以通過呼叫info locals命令得到當前堆疊幀中所有區域變數的值串列

在有些情況下,可能希望檢查給定地址的記憶體,而不是通過變數的名稱,GDB為這種目的提供了x命令,

print和display命令允許指定可選的格式,如”(gdb) p/x y”,會以十六進制格式顯示變數,而不是十進制格式,其它常用的格式為c表示字符(character),s表示字串(string),f表示浮點(floating-point),

可以臨時禁用某個顯示項,例如”(gdb) dis disp 1”,臨時禁用顯示串列中的條目1.如果不知道條目號,可以通過info disp命令檢查,要重新啟用條目,使用enable,例如”(gdb) enable disp 1”,要完全洗掉顯示的條目,使用undisplay,例如”(gdb) undisp 1”,

3.3 設定變數:”(gdb) set x = 12”,會將x的當前值改成12,可以通過GDB的set args命令設定程式的命令列引數,如”(gdb) set args 1 52 19 11”,并不會立即將argv[1]改成1,argv[2]改成52,等等,直到下次執行run命令時才會發生這些變化,GDB有用來檢查當前函式引數的info args命令

3.4 GDB自己的變數:

(1).使用值歷史:GDB的print命令的輸出值被標為$1、$2等,這些值統稱為值歷史,在將來執行print命令時使用這樣的值歷史會比較方便,如”(gdb) p *$1”,

(2).方便變數(convenience variable):會根據C規則改變值,

4. 程式崩潰處理

4.2 核心檔案:如果在程式運行期間創建了核心檔案(core file,俗稱轉儲核心),則可以打開除錯器(比如GDB)上的該檔案,然后開始常規GDB操作,

核心檔案包含程式崩潰時對程式狀態的詳細描述:堆疊的內容(或者,如果程式是多執行緒的,則是各個執行緒的堆疊),CPU暫存器的內容(同樣,如果程式是多執行緒的,則是每個執行緒上的一組暫存器值),程式的靜態分配變數的值(全域與static變數),等等,

大多數現代shell都會在一開始就防止撰寫核心檔案,在bash中,可以使用ulimit命令控制核心檔案的創建,”$ ulimit -c n”,其中n是核心檔案的最大大小,以千位元組為單位,超過nKB的任何核心檔案都不會被編寫,如果沒有指定n,shell就會顯示核心檔案上的當前限制,如果允許任意大小的核心檔案,可以使用:”$ ulimit -c unlimited”,

如果程式的源代碼不可用,或者可執行檔案不是用增強的符號表編譯的,啥訓當我們沒有計劃除錯可執行檔案,核心檔案可能都不會有太大的用處,

core file的使用示例可參考:https://blog.csdn.net/fengbingchun/article/details/97113451

4.3 擴展示例:

在除錯會話期間,修改代碼時永遠不要退出GDB,這樣就不必費時間來啟動,可以保留我們的斷點,等等,類似地,我們要保持文本編輯器打開,在除錯時的兩次編譯之間留在同一個編輯器會話中,我們可以充分利用編輯器的”撤銷”功能,例如,除錯程序中的一個常見策略是臨時洗掉部分代碼,以便集中精力于你認為存在程式錯誤的余下部分,完成檢查后,只要使用編輯器的撤銷功能恢復被洗掉的代碼行即可,因此,在螢屏上我們通常有一個GDB視窗,以及一個編輯器視窗,我們還打開了第三個視窗用于執行編譯器命令,甚至最好是通過編輯器執行命令,

記住,當GDB注意到重新編譯了程式后,它會自動加載新的可執行檔案,因此同樣不需要退出和重啟GDB

5. 多活動背景關系中的除錯

5.1 除錯客戶/服務器網路程式:socket

5.2 除錯多執行緒代碼:

查看指定執行緒的堆疊,如執行緒3,可執行”(gdb) thread 3”,再執行”(gdb) bt”,多執行緒程式的運行有一定的隨機性,

下面是與執行緒相關的GDB命令用法匯總:

(1).info threads:給出關于當前所有執行緒的資訊,帶有”*”號表示當前執行緒;

(2).thread 3:改成執行緒3;

(3).break 88 thread 3:當執行緒3到達源代碼行88時停止執行;

(4).break 88 thread 3 if x == y:當執行緒3到達源代碼行88,并且變數x和y相等時停止執行,

5.3 除錯并行應用程式:共享記憶體和訊息傳遞、MPI

5.4 擴展示例:OpenMP

6. 特殊主題

6.1 根本無法編譯或加載:

6.2 除錯GUI程式:

7. 其它工具

8. 對其它語言使用GDB

GitHub:https://github.com/fengbingchun/Messy_Test

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/182585.html

標籤:其他

上一篇:2020.10自考總結

下一篇:關于第四次自考,在問題中成長

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more