官术网_书友最值得收藏!

1.4 調(diào)試

軟件工程師最重要的技能之一是高效、有效的調(diào)試能力。大多數(shù)開(kāi)發(fā)環(huán)境都有調(diào)試工具。在Windows、macOS和Linux上,這些調(diào)試工具都很好。學(xué)會(huì)使用這些工具是一項(xiàng)投資,可以很快得到回報(bào)。本節(jié)將簡(jiǎn)要介紹如何使用調(diào)試器來(lái)逐步調(diào)試代碼清單1-8中的程序。你可以跳到與自己的環(huán)境最相關(guān)的部分。

1.4.1 Visual Studio

Visual Studio有一個(gè)內(nèi)置的優(yōu)秀調(diào)試器。建議在Debug配置中調(diào)試程序。這將使工具鏈以增強(qiáng)調(diào)試體驗(yàn)為目標(biāo)。在Release模式下進(jìn)行調(diào)試的唯一原因是診斷一些在Release模式下出現(xiàn)而在Debug模式下沒(méi)有出現(xiàn)的罕見(jiàn)情況。

1)打開(kāi)main.cpp,找到main的第一行。

2)單擊main第一行對(duì)應(yīng)的行號(hào)左邊的空白處,插入一個(gè)斷點(diǎn),此時(shí)會(huì)出現(xiàn)一個(gè)紅色的圓圈,如圖1-4所示。

圖1-4 插入一個(gè)斷點(diǎn)

3)選擇Debug(調(diào)試)→Start Debugging(啟動(dòng)調(diào)試)。程序?qū)⑦\(yùn)行到插入斷點(diǎn)的那一行。調(diào)試器將停止程序的執(zhí)行,這時(shí)會(huì)出現(xiàn)一個(gè)黃色的箭頭,指示要運(yùn)行的下一條指令,如圖1-5所示。

4)選擇Debug(調(diào)試)→Step Over(單步跳過(guò))。單步跳過(guò)是在不“進(jìn)入”任何函數(shù)調(diào)用的情況下執(zhí)行指令。默認(rèn)情況下,單步跳過(guò)的鍵盤(pán)快捷鍵是<F10>。

5)因?yàn)橄乱恍袑⒄{(diào)用step_function,所以選擇Debug(調(diào)試)→Step Into(單步調(diào)試)來(lái)調(diào)用step_function并在該函數(shù)的第一行中斷。通過(guò)單步調(diào)試或單步跳過(guò)可繼續(xù)調(diào)試這個(gè)函數(shù)。默認(rèn)情況下,單步調(diào)試的鍵盤(pán)快捷鍵是<F11>。

圖1-5 調(diào)試器在斷點(diǎn)處停止執(zhí)行

6)要讓執(zhí)行返回到main,請(qǐng)選擇Debug(調(diào)試)→Step Out(單步跳出)。默認(rèn)情況下,單步跳出的鍵盤(pán)快捷鍵是<Shift+F11>。

7)通過(guò)選擇Debug→Windows→Auto,檢查Autos窗口。我們可以看到一些重要變量的當(dāng)前值,如圖1-6所示。

圖1-6 Autos窗口顯示當(dāng)前斷點(diǎn)處的變量值

可以看到,num1被設(shè)置為42,result1被設(shè)置為1。為什么num2有一個(gè)亂七八糟的值?因?yàn)?b>num2初始化為0的過(guò)程還沒(méi)有發(fā)生:這是下一條指令要執(zhí)行的。

注意 調(diào)試器剛剛強(qiáng)調(diào)了一個(gè)非常重要的底層細(xì)節(jié):分配對(duì)象的存儲(chǔ)空間和初始化對(duì)象的值是兩個(gè)不同的步驟。第4章將介紹更多關(guān)于存儲(chǔ)空間分配和對(duì)象初始化的知識(shí)。

Visual Studio調(diào)試器支持更多的功能。欲了解更多信息,請(qǐng)查看Visual Studio文檔。

1.4.2 Xcode

Xcode也有一個(gè)內(nèi)置的優(yōu)秀調(diào)試器,它已完全集成在IDE中。

1)打開(kāi)main.cpp,找到main的第一行。

2)單擊第一行,然后選擇Debug(調(diào)試)→Breakpoints(斷點(diǎn))→Add Breakpoint at Current Line(在當(dāng)前行設(shè)置斷點(diǎn)),此時(shí)會(huì)出現(xiàn)一個(gè)斷點(diǎn),如圖1-7所示。

3)選擇Run(運(yùn)行),程序?qū)⑦\(yùn)行到插入斷點(diǎn)的那一行。調(diào)試器將停止程序的執(zhí)行,此時(shí)會(huì)出現(xiàn)一個(gè)綠色的箭頭,指示下一條要運(yùn)行的指令,如圖1-8所示。

圖1-7 插入一個(gè)斷點(diǎn)

圖1-8 調(diào)試器在斷點(diǎn)處停止執(zhí)行

4)選擇Debug(調(diào)試)→Step Over(單步跳過(guò))來(lái)執(zhí)行指令,而不“進(jìn)入”任何函數(shù)調(diào)用。默認(rèn)情況下,單步跳過(guò)的鍵盤(pán)快捷鍵是<F6>。

5)因?yàn)橄乱恍写a會(huì)調(diào)用step_function,所以選擇Debug(調(diào)試)→Step Into(單步調(diào)試)來(lái)調(diào)用step_function并在該函數(shù)第一行中斷。通過(guò)單步調(diào)試或單步跳過(guò)可繼續(xù)調(diào)試這個(gè)函數(shù)。默認(rèn)情況下,單步跳過(guò)的鍵盤(pán)快捷鍵是<F7>。

6)要讓執(zhí)行返回到main,請(qǐng)選擇Debug(調(diào)試)→Step Out(單步跳出)。默認(rèn)情況下,單步跳出的鍵盤(pán)快捷鍵是<F8>。

7)檢查main.cpp屏幕底部的Autos窗口,可以看到一些重要變量的當(dāng)前值,如圖1-9所示。

圖1-9 Autos窗口顯示當(dāng)前斷點(diǎn)處的變量值

可以看到,num1被設(shè)置為42,result1被設(shè)置為1。為什么num2有一個(gè)亂七八糟的值?因?yàn)?b>num2初始化為0的過(guò)程還沒(méi)有發(fā)生:這是下一條指令要執(zhí)行的。

Xcode調(diào)試器支持更多的功能。欲了解更多信息,請(qǐng)查看Xcode文檔。

1.4.3 用GDB和LLDB對(duì)GCC和Clang進(jìn)行調(diào)試

GNU項(xiàng)目調(diào)試器(GNU project DeBugger,GDB)是一個(gè)強(qiáng)大的調(diào)試器(https://www.gnu.org/software/gdb/)。我們可以使用命令行與GDB交互。要在用g++clang++編譯時(shí)啟用調(diào)試支持,必須添加-g標(biāo)志。

包管理器很可能有GDB。例如,要用高級(jí)包工具(APT)安裝GDB,請(qǐng)輸入以下命令:

Clang也有一個(gè)很好的調(diào)試器,叫作LLDB(Low Level DeBugger),詳見(jiàn)https://lldb.llvm.org/。它與本節(jié)中的GDB命令兼容,所以為了簡(jiǎn)潔起見(jiàn),這里不具體介紹LLDB。我們可以使用LLDB來(lái)調(diào)試由GCC編譯的程序,也可以使用GDB來(lái)調(diào)試用Clang編譯的程序。

注意 Xcode在后臺(tái)使用LLDB。

使用GDB調(diào)試代碼清單1-8中的程序,請(qǐng)遵循以下步驟:

1)在命令行中,切換到存放頭文件和源文件的文件夾。

2)啟用調(diào)試支持的同時(shí)編譯程序:

3)使用gdb調(diào)試程序應(yīng)該可以看到以下交互式控制臺(tái)會(huì)話:

4)要插入斷點(diǎn),可以使用break命令,該命令需要一個(gè)參數(shù),該參數(shù)對(duì)應(yīng)源文件的名稱和要插入斷點(diǎn)的行(用冒號(hào)分開(kāi))。例如,假設(shè)我們想在main.cpp的第一行(對(duì)應(yīng)代碼清單1-8的第5行,是否需要調(diào)整位置取決于編寫(xiě)代碼的方式)中斷。在(gdb)提示符下可使用以下命令創(chuàng)建斷點(diǎn):

5)我們也可以通過(guò)函數(shù)名告訴gdb在某個(gè)特定的函數(shù)處中斷:

6)不管怎樣,現(xiàn)在可以執(zhí)行程序了:

7)要單步調(diào)試指令,可用step命令來(lái)追蹤程序的每一行,包括函數(shù)內(nèi)部的單步調(diào)試:

8)要繼續(xù)單步調(diào)試,可按<Enter>鍵,重復(fù)上一個(gè)命令:

9)要跳出函數(shù)的調(diào)用,可以使用finish命令:

10)要執(zhí)行一條指令而不進(jìn)入函數(shù),可以使用next命令:

11)要檢查變量的當(dāng)前值,可以使用info locals命令:

注意,任何尚未被初始化的變量都不會(huì)有合理的值。

12)若要繼續(xù)執(zhí)行直到下一個(gè)斷點(diǎn)(或程序結(jié)束),可以使用continue命令:

13)使用quit命令可以隨時(shí)退出gdb。

GDB支持更多的功能。欲了解更多信息,請(qǐng)查看https://sourceware.org/gdb/current/onlinedocs/gdb.html/。

主站蜘蛛池模板: 上虞市| 繁峙县| 弥勒县| 志丹县| 洛隆县| 惠州市| 无锡市| 安平县| 沧州市| 南投县| 南陵县| 凤城市| 绥中县| 伊通| 西峡县| 木兰县| 台东市| 东乡族自治县| 大名县| 若尔盖县| 通许县| 佛山市| 鸡东县| 乌鲁木齐县| 易门县| 阜宁县| 旺苍县| 钟山县| 棋牌| 抚顺县| 鄢陵县| 静海县| 鄱阳县| 鄂温| 嵊州市| 滨州市| 山东省| 彭州市| 伊宁市| 四平市| 尚义县|