成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

別再說調試器不好用了!

譯文 精選
開發 開發工具
每個調試器都支持斷點。在代碼中的某一行上設置斷點,當執行到達該行時,程序將停止。但現代調試器可以做的遠遠不止這些。

?作者 | werat

譯者 | 言征

策劃 | 云昭

當人們說“調試器是無用的,使用日志和單元測試更好”時,我懷疑他們中的許多人認為調試器只能在某些行上設置斷點,一步一步地通過代碼,并檢查變量值。雖然任何合理的調試器都可以做到這一切,但這只是冰山一角。想想看;40年前,我們就已經可以通過這一代碼了,當然有些事情已經改變了嗎?

1、斷點

每個調試器都支持斷點。在代碼中的某一行上設置斷點,當執行到達該行時,程序將停止。但現代調試器可以做的遠遠不止這些。

列斷點。你知道不僅可以在特定的行上設置斷點,還可以在行+列上設置斷點嗎?如果一行源代碼包含多個表達式(例如,foo() + bar() + baz()等函數的調用) ,那么可以在行的中間放置一個斷點,并直接跳到該執行點。LLDB已經支持了一段時間,而IDE支持可能會有所欠缺。Visual Studio有一個名為Stepinto-specific的命令,它解決了一個類似的問題——如果在同一行上有多個調用,它允許你選擇單步執行哪個函數。

條件斷點。通常,你可以在斷點上設置一系列額外的選項。例如,你可以指定“命中計數”條件,以僅在命中某一次數或每N次迭代后觸發斷點。或者使用更強大的概念——條件表達式——在應用程序處于特定狀態時觸發斷點。例如,只有在主線程和monster->name == "goblin"上發生命中時,才能觸發斷點。Visual Studio調試器還支持“when changes”類型的條件表達式–當 monster->hp  的值與上次命中斷點時相比,發生變化時觸發斷點。

跟蹤斷點(或跟蹤點)。但如果斷點沒有中斷呢??? 不要再說了,我們可以向輸出輸出一條消息,而不是停止執行。而不僅僅是一個簡單的字符串,比如“getherelol”;消息可以包含計算和嵌入程序值的表達式,例如“iteration #{i},當前monster是{monster->name}”。本質上,我們將printf調用注入到程序中的隨機位置,而無需重新構建和重新啟動程序。這樣代碼就會很整潔。

數據斷點。斷點也不必位于特定的行、地址或函數上。所有現代調試器都支持數據斷點,這意味著每當內存中的某個特定位置被寫入時,程序都可以停止。你不明白為什么這個怪物會隨機死亡嗎?在monster->hp的位置設置一個數據斷點,并在值發生變化時得到通知。這在調試某些代碼正在寫入不應該寫入的內存的情況下尤其有用。將其與打印消息相結合,你將獲得一個強大的日志記錄機制,這是printf無法實現的!

2、數據可視化

另一個基本的調試功能——數據檢查。任何調試器都可以顯示變量的值,但好的調試器為自定義可視化工具提供了豐富的功能。GDB有外觀漂亮的打印,LLDB有數據格式化程序,Visual Studio有NatVis。所有這些機制都非常靈活,在可視化對象時幾乎可以做任何事情。對于檢查復雜的數據結構和不透明的指針來說,這是一個非常寶貴的功能。例如,開發者不必擔心哈希圖的內部表示,只需查看鍵/值條目的列表即可。

圖片

這些可視化工具非常有用,但好的調試器可以做得更好。如果你有一個GUI,為什么只局限于“文本”可視化?調試器可以顯示數據表和圖表(例如SQL查詢的結果)、渲染圖像(例如圖標或紋理)、播放聲音等。圖形界面在這里打開了無限的可能性,這些可視化工具甚至不難實現。

圖片

Visual Studio 中的 Image Watch

3、表達式求值

大多數現代調試器都支持表達式求值。其思想是,你可以鍵入表達式(通常使用程序的語言),調試器將使用程序狀態作為上下文對其進行評估。例如,鍵入 monsters[i]->get_name()  ,調試器顯示“goblin”(其中monsters和i是當前范圍中的變量)。顯然,在不同的調試器和不同的語言中,實現有很大的差異。

例如,Visual Studio C++調試器實現了C++的推理子集,甚至可以執行函數調用(有一些限制)。它使用基于解釋器的方法,因此它非常快速且“安全”,但不允許執行真正的任意代碼。GDB也做了同樣的事情。另一方面,LLDB使用實際的編譯器(Clang)將表達式編譯為機器代碼,然后在程序中執行它(盡管在某些情況下,它可以使用解釋作為優化)。這實際上允許執行任何有效的C++!

(lldb) expr
Enter expressions, then terminate with an empty line to evaluate:
1: struct Foo {
2: int foo(float x) { return static_cast<int>(x) * 2; }
3: };
4: Foo f;
5: f.foo(3.14);
(int) $0 = 6

表達式求值是一個非常強大的功能,它為程序分析和實驗開辟了許多可能性。通過調用函數,你可以探索程序在不同情況下的行為,甚至可以更改其狀態和執行。調試器還經常使用表達式求值來增強其他功能,如條件斷點、數據監視和數據格式化程序。

4、并發和多線程

開發和調試多線程應用程序很困難。許多與并發相關的錯誤很難再現,尤其在調試器下運行時,程序運行的行為飄忽不定。不過,好的調試器可以在這里提供很多幫助。

調試器可以節省大量時間。一個很好的例子是調試死鎖。如果你設法使應用程序處于死鎖狀態,那么你就幸運了!一個好的調試器將顯示所有線程的調用堆棧以及它們之間的依賴關系。很容易看出哪些線程正在等待哪些資源(例如互斥鎖)以及誰在占用這些資源。不久前,我寫了一篇關于在VisualStudio中調試死鎖的案例的文章,看看它有多簡單。

開發和調試多線程應用程序的一個非常常見的問題是,很難控制執行哪些線程的時間和順序。許多調試器都遵循“全有或全無”策略,這意味著當斷點命中時,整個程序(即其所有線程)都會停止。如果單擊“繼續”,所有線程將再次開始運行。如果程序中的線程不重疊,這可以正常工作,但當相同的代碼由不同的線程執行,并且以隨機順序命中相同的斷點時,這會變得非常煩人。

一個好的調試器可以凍結和解凍線程。你可以選擇哪些線程應該執行,哪些線程應該休眠。這使得調試高度并行化的代碼更加容易,而且你還可以模擬不同的競爭條件和死鎖。在Visual Studio中,你可以在UI中凍結和解凍線程,而GDB有一種叫做不停止模式的功能。RemedyBG有一個非常方便的UI,你可以快速切換到“solo”模式并返回。

圖片

之前提到,調試器可以顯示線程之間的依賴關系。一個好的調試器還支持協同程序(綠色線程、任務等),并提供一些工具來可視化當前程序狀態。例如,Visual Studio有一個叫做并行堆棧的功能。在此窗口中,你可以快速了解整個程序狀態,并查看不同線程正在執行的代碼。

圖片

5、熱重載

想象一個典型的調試會話。你運行程序,加載數據,執行一些操作,最后到達發現錯誤的位置。你設置了一些斷點,一步一步,突然意識到某個“if”條件是錯誤的——它應該是 >=  而不是 > 。你接下來要做什么?停止程序,修復條件,重建程序,運行它,加載數據,執行一些操作…等等。現在是2023年,你下一步要做什么?

修復條件并保存文件。很輕松動兩下,程序就會接收代碼中的更改!它沒有重新啟動,也沒有失去狀態,它就在你離開它的地方。你立即發現你的修復程序不正確,實際上應該是 ==  。再次修復。

這種神奇的特性被稱為熱重載——一個好的調試器可以在不重新啟動的情況下獲取源代碼中的更改并將其應用于實時運行的程序。許多使用動態或基于VM的語言(如JavaScript、Python或Java)的人都知道這是一件事,但并不是所有人都意識到C++或Rust等編譯語言也有可能這樣做!例如,Visual Studio支持通過“編輯并繼續”對C++進行熱重新加載。它確實有一長串的限制和不支持的更改,但它在許多常見場景(演示)中仍能正常工作。

另一項令人驚嘆的技術是Live++——可以說是當今最好的熱重載解決方案。它支持不同的編譯器和構建系統,可以與任何IDE或調試器一起使用。不受支持的場景列表要短得多,其中許多都不是基本的限制——只要付出足夠的努力,熱重新加載幾乎可以處理任何類型的更改。

熱重新加載不僅僅是將更改應用于實時程序。一個好的熱重新加載實現可以幫助從諸如訪問違規之類的致命錯誤中恢復,或者改變不同編譯單元的優化級別(以及可能的任何其他編譯器標志)。它還可以遠程執行,同時執行多個進程。

6、Time travel 

有沒有遇到過這樣的問題,就是你在代碼中踩得太遠了?只是一點點,但傷害已經造成了。這時候,我們只能重新啟動程序并重試,并后退幾步。這可能比熱重載更神奇,但一個好的調試器實際上可以及時運行。后退一步或設置一個斷點,然后反向運行,直到它被擊中,就像是2023年,而不是1998年一樣。

許多調試器都支持這種操作。GDB通過記錄每個指令所做的寄存器和內存修改來實現時間旅行,這使得撤消更改變得很簡單。然而,這會導致顯著的性能開銷,因此在非交互模式下可能不太實用。另一種流行的方法,則基于大多數程序執行是確定性的觀察。每當發生不確定的事情(系統調用、I/O等)時,我們都可以對程序進行快照,然后通過將其倒回到最近的快照并從那里執行代碼,隨時重建程序狀態。這基本上就是UDB、WinDBG和rr所做的。

圖片

 ↑ 使用 Time Travel Debug for C/C++

7、全方位調試

最后一件事,是在調試場景中徹底改變游戲規則。傳統調試有很多缺點。記錄和回放是向前邁出的一大步,但如果除了記錄可再現的程序跟蹤之外,我們還預先計算了所有單獨的程序狀態,將它們存儲在數據庫中,并建立了索引以進行有效查詢,會怎么樣?

這聽起來是不可能的,但實際上卻出奇地可行。結果表明,程序狀態壓縮得很好,每條指令的存儲量小于1bit!

這種方法被稱為全知調試,它不僅解決了傳統調試器所面臨的一系列問題(例如堆棧展開),而且還打開了我們以前認為不可能實現的可能性。隨著整個程序歷史記錄和索引,你可以問一些問題,比如“變量寫了多少次,寫在哪里?”、“哪個線程釋放了這塊內存?”甚至“這個特定的像素是如何渲染的?”。

還推薦觀看羅伯特·奧卡拉漢(Robert O'Callahan,rr的作者)的《2022年的調試狀態》(The State Of Debugging in 2022),這本書很好地說明了為什么全方位調試是未來,我們應該對工具提出更高的要求。

盡管這個想法可以追溯到幾十年前,但高效實用的實現很難。現代全知調試器的一個很好的例子是Pernosco。它有一長串受支持的功能和用例,甚至簡單的演示看起來都難以置信。

另一個很棒的工具是WhiteBox。它在編寫代碼時編譯、運行和“調試”代碼,為開發者提供對程序流程和結構的寶貴見解。它記錄執行情況,并允許你隨時檢查程序狀態。不過它仍然處于測試階段。

7、調式or不調試? 

每個現有的調試器都有其優缺點,不存在真正的銀彈。在某些情況下,日志記錄更方便,而在其他情況下,使用Time Travel調試器則可以將錯誤調查的時間,從幾天縮短到幾分鐘。調試技術已經取得了長足的進步,有很多有趣的特性值得一看。開發者在使用過程中也可以從本地調試器供應商那里,提出改善的需求。

那么,你最喜歡調試器的哪項功能呢?

參考鏈接:https://werat.dev/blog/what-a-good-debugger-can-do/

責任編輯:武曉燕 來源: 51CTO技術棧
相關推薦

2021-02-17 21:33:39

路由器產品網絡

2025-01-20 08:10:00

AI模型研究

2021-05-13 09:27:13

JavaThreadLocal線程

2023-10-24 08:01:38

String傳統

2014-10-20 10:53:13

ArubaWi-Fi無線網絡

2021-05-10 07:35:11

SwaggeYApi部署

2019-05-09 18:24:28

Windows 10Windows操作系統

2014-02-21 10:20:40

2022-05-27 21:56:55

索引存儲MySQL 存儲引擎

2010-03-01 11:06:52

Python 調試器

2020-03-16 10:05:13

EmacsGUDLinux

2023-10-25 16:36:06

數字化轉型IT系統

2014-11-04 10:15:28

Android

2020-10-19 08:14:58

Windows10

2009-12-14 10:57:34

Ruby調試器

2021-08-16 13:44:37

手機電子日本

2020-03-19 14:30:13

Windows觸摸板MacBook

2011-08-31 16:51:12

Lua調試器

2023-02-28 11:39:55

CMake腳本項目

2019-10-31 16:10:48

Windows 10Windows技巧
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 在线观看中文字幕dvd播放 | 欧美一区二区三区视频 | 成年人黄色一级片 | 久久久久久久国产 | 美女视频一区二区三区 | 亚洲综合热 | 日本高清aⅴ毛片免费 | 国产乱精品一区二区三区 | 五月激情六月婷婷 | 久久久久久久国产精品 | 国产精品一区二区三区久久 | 毛色毛片免费看 | 99久久精品免费看国产高清 | 国产自产c区| 欧美日韩国产在线观看 | 欧美日韩国产精品激情在线播放 | 91久久精品国产91久久性色tv | 国产高清在线观看 | 国产色| 秋霞av国产精品一区 | 中文一区 | 国产黄色网 | 国产精品天堂 | 日本午夜视频 | 日韩色综合 | av一区二区在线观看 | 97精品超碰一区二区三区 | 激情国产在线 | 另类专区亚洲 | 久久大陆 | 国产精品美女久久久久 | 一级片免费视频 | 亚洲天堂久久 | 亚洲人va欧美va人人爽 | 久久一二区| 亚洲精品乱 | 日韩精品一区二区不卡 | 免费在线观看一区二区 | 亚洲欧美国产毛片在线 | 亚洲国产精品一区二区久久 | 免费毛片网站在线观看 |