閱讀其他語言: English Português 中文
有許多偵錯器教學可以教您如何設定行斷點、記錄值或計算表達式。雖然這些知識本身就為您提供了許多工具來調試應用程序,但實際場景可能會更複雜一些,並且需要更高級的方法。
在本文中,我們將學習如何在對專案沒有太多了解的情況下找到導致 UI 崩潰的程式碼,並即時修復損壞的程式碼。
如果您想遵循該範例,請先複製此儲存庫:https://github.com/flounder4130/debugger-example
假設您有一個複雜的應用程序,當您執行某些操作時該應用程式崩潰了。您知道如何重現錯誤,但困難在於您不知道程式碼的哪一部分負責此功能。
在我們的範例應用程式中,當您按一下按鈕 N時會發生崩潰。然而,要找到負責此操作的程式碼並不那麼容易:
讓我們看看如何使用調試器來找到它。
方法斷點相對於行斷點的優點是它們可以在整個類別層次結構中使用。這對我們的例子有什麼用?
如果您查看範例項目,您會發現所有操作類別都派生自 Action 接口,並具有單一方法:perform()。
在此介面方法上設定方法斷點將在每次呼叫派生方法之一時暫停應用程式。若要設定方法斷點,請按一下宣告該方法的行。
啟動偵錯會話並點選按鈕N。應用程式在 ActionImpl14 上暫停。現在我們知道這個按鈕對應的程式碼在哪裡了。
雖然在本文中我們的重點是查找錯誤,但當您想要了解某些內容在大型程式碼庫中如何運作時,此技術也可以為您節省大量時間。
帶有方法斷點的方法運作得很好,但它是基於我們了解父介面的假設。如果這個假設是錯誤的,或者我們因為其他原因不能使用這種方法怎麼辦?
好吧,我們甚至可以在沒有斷點的情況下做到這一點。點擊按鈕 N,當應用程式掛起時,請前往 IntelliJ IDEA。從主選單中,選擇運行|調試操作|暫停計劃.
應用程式將暫停,允許我們在執行緒和變數標籤中檢查執行緒的當前狀態。這讓我們了解應用程式當時正在做什麼。由於它掛起,我們可以識別導致阻塞的方法並將其追溯到呼叫網站。
與更傳統的線程轉儲相比,這種方法具有一些優勢,我們將很快介紹。例如,它以方便的形式為您提供有關變數的信息,並允許您控製程式的進一步執行。
提示:有關暫停程序的更多提示和技巧,請參閱無斷點調試和 Debugger.godMode()
最後,我們可以使用執行緒轉儲,這並不是嚴格意義上的偵錯器功能。無論您是否使用調試器,它都可用。
點擊按鈕N。當應用程式崩潰時,請轉到 IntelliJ IDEA。從主選單中,選擇運行|調試操作|獲取線程轉儲.
探索左側的可用線程,在AWT-EventQueue中,您將看到導致問題的原因。
The disadvantage of thread dumps is that they only provide a snapshot of the state of the program at the time they were made. You cannot use thread dumps to explore variables or control program execution.
In our example, we don't need to resort to a thread dump. However, I still wanted to mention this technique as it can be useful in other cases, such as when you are trying to debug an application that has been launched without the debugging agent.
Regardless of the debugging technique, we arrive at ActionImpl14. In this class, someone intended to do the work in a separate thread, but confused Thread.start() with Thread.run(), which runs code in the same thread as the calling code.
IntelliJ IDEA's static analyzer even warns us about this at design time:
A method that does heavy lifting (or sleeps a lot in this case) is called on the UI thread and blocks it until the method finishes. That's why we can't do anything in the UI for a while after clicking theButton N.
Now that we have discovered the cause of the error, let's correct the problem.
We could stop the program, recompile the code and then run it again. However, it is not always wise to redeploy the entire application just because a small change was made.
Let's do it the smart way. First, fix the code using the suggested quick fix:
After the code is ready, clickRun|Debugging Actions|Reload Changed Classes. A balloon appears, confirming that the new code has arrived in the VM.
Let's go back to the app and check. ClickingButton Nno longer crashes the app.
Tip: Keep in mind that HotSwap has its limitations. If you're interested in extended HotSwap capabilities, it might be a good idea to take a look at advanced tools like DCEVM or JRebel
Using our reasoning and a couple of debugger features, we were able to locate the code that was causing a UI crash in our project. We then proceeded to fix the code without wasting time on recompilation and redistribution, which can be lengthy in real-world projects.
I hope you find the techniques described useful. Let me know what you think!
If you are interested in more articles related to debugging and profiling, check out some of my other articles:
Stay tuned for more!
以上是調試無響應的應用程式的詳細內容。更多資訊請關注PHP中文網其他相關文章!