1.簡介gdb調(diào)試工具1.1程序發(fā)布版本
通常,程序發(fā)布有兩種版本:調(diào)試模式(debug)和發(fā)布模式(release)。在Linux中,使用gcc/g++編譯時,默認(rèn)生成的是release模式。要使用gdb進(jìn)行調(diào)試,必須在編譯時加入-g選項,以便生成debug模式的程序。
1.2前期準(zhǔn)備
開始調(diào)試前,需要安裝gdb和搭建環(huán)境。gdb通常是系統(tǒng)自帶的,可以通過gdb –version命令檢查其是否存在及版本信息。
環(huán)境準(zhǔn)備包括準(zhǔn)備一個可用的源文件,這里以mycode.c為例,其生成的程序?qū)?biāo)記為mycode。
以下是一個簡單的c語言代碼示例,作為mycode.c的內(nèi)容:
在編譯時,-g選項表示生成的是調(diào)試版本,Makefile文件的其他內(nèi)容保持不變。
1.3調(diào)試的開始與結(jié)束
啟動gdb調(diào)試只需在gdb命令后加上當(dāng)前目錄下的生成文件名。看到gdb提示符(gdb)和閃爍的光標(biāo),即可輸入調(diào)試命令。
輸入q并按下回車鍵,即可結(jié)束調(diào)試過程。
1.4調(diào)試相關(guān)命令1.4.1設(shè)置斷點
這里的7和8表示程序的第7行和第8行設(shè)置斷點。
1.4.2單步執(zhí)行
使用next命令,程序會按代碼順序逐行執(zhí)行。
1.4.3運行程序
使用run命令啟動程序,運行到斷點處暫停。
1.4.4查看變量值
使用print x命令查看變量x的值。
1.4.5斷點間跳轉(zhuǎn)
使用continue命令可從第一個斷點直接跳轉(zhuǎn)到第二個斷點。
1.4.6查看調(diào)試程序代碼
使用l 0命令從第0行開始顯示代碼,多次執(zhí)行l(wèi)命令會逐步顯示所有代碼。
2.進(jìn)程入門2.1簡要回顧
上次我們討論了操作系統(tǒng)及其與硬件架構(gòu)的層級關(guān)系。操作系統(tǒng)通過驅(qū)動程序管理軟硬件資源,并通過描述和組織的方式實現(xiàn)對這些資源的管理。
2.2進(jìn)程初識
加載到操作系統(tǒng)中的程序就是進(jìn)程。操作系統(tǒng)可以同時運行多個進(jìn)程。
當(dāng)需要加載多個進(jìn)程時,操作系統(tǒng)需要管理這些進(jìn)程,管理方式是先描述后組織。
當(dāng)一個進(jìn)程加載到內(nèi)存中成為真正的進(jìn)程時,操作系統(tǒng)會創(chuàng)建一個描述進(jìn)程的結(jié)構(gòu)體對象,稱為PCB(進(jìn)程控制塊)。PCB類似于面向對象編程中的對象,包含進(jìn)程的所有屬性。
2.3進(jìn)程屬性
PCB包含狀態(tài)、進(jìn)程編號、優(yōu)先級等屬性。
根據(jù)PCB,操作系統(tǒng)會將進(jìn)程的代碼和數(shù)據(jù)加載到內(nèi)存中。
進(jìn)程=內(nèi)核PCB+自己的數(shù)據(jù)和代碼。
管理多個進(jìn)程類似于對單鏈表進(jìn)行增刪查改操作。
PCB中包含指向代碼和數(shù)據(jù)的指針,操作系統(tǒng)只需管理PCB,PCB則管理代碼和數(shù)據(jù)。
多個進(jìn)程通過指針連接成鏈表,進(jìn)程管理相當(dāng)于對鏈表進(jìn)行增刪查改操作。每個PCB僅管理自己的數(shù)據(jù)和代碼,排隊時是PCB在排隊,當(dāng)輪到某個PCB時,它會調(diào)用自己的數(shù)據(jù)和代碼。
2.3Linux中的PCB
在Linux中,task_struct是PCB的一種數(shù)據(jù)類型,包含標(biāo)識符、狀態(tài)、優(yōu)先級、程序計數(shù)器、上下文數(shù)據(jù)、I/O狀態(tài)記錄、內(nèi)存指針等屬性。
Linux使用雙向鏈表組織進(jìn)程。
2.4查看進(jìn)程
使用ls /proc命令查看進(jìn)程,/proc是Linux中的一個目錄。
當(dāng)前目錄概念:創(chuàng)建文件時,若未指定位置,系統(tǒng)會在當(dāng)前目錄下自動創(chuàng)建文件,因為進(jìn)程記住自己的目錄位置。
使用kill -9 進(jìn)程編號命令可以終止進(jìn)程。
2.5查看進(jìn)程標(biāo)識符
進(jìn)程標(biāo)識符是進(jìn)程的一個屬性,可以使用getpid系統(tǒng)調(diào)用查看當(dāng)前進(jìn)程的標(biāo)識符,使用getppid查看父進(jìn)程的標(biāo)識符。
任何進(jìn)程都是bash進(jìn)程的子進(jìn)程,bash進(jìn)程是所有進(jìn)程的父進(jìn)程,可以通過相應(yīng)命令查看其標(biāo)識符。
2.6創(chuàng)建進(jìn)程
運行程序時會生成一個進(jìn)程。
使用fork系統(tǒng)調(diào)用可以創(chuàng)建新進(jìn)程,fork返回兩個值,父子進(jìn)程共享代碼,但數(shù)據(jù)在各自的內(nèi)存空間中獨立存在。