除錯js碰到迴圈斷點(debugger),應該怎麼做?

Gladyu發表於2018-03-29

文章更新了新內容,更加深入分析了一波

作為前端開發來說,js除錯是一項必備的技能。無論是要查詢bug,還是想了解別人程式碼的邏輯,js除錯都是一種可以幫助你節省時間的方法。

除錯js碰到迴圈斷點(debugger),應該怎麼做?
這是我平時使用的chrome的除錯介面。選擇它的原因,一是功能真的十分強大,第二個就是新特性支援的比較快(尤其是Google Chrome Canary 版,擁有新版 Chrome 的最新功能,這是專為開發者和早期使用者設計的版本,有時可能會造成瀏覽器徹底當機,下載直通車,你可以去這裡看看它的功能和特性)

這篇文章的目的不是分享 像格式程式碼,設定斷點,檢視呼叫棧,檢視變數等一系列除錯工具功能的使用,這種網上已經有很多好的文章了,本文主要分析工作中遇到的迴圈debugger問題,如下圖:

除錯js碰到迴圈斷點(debugger),應該怎麼做?

有時候我們在扒別人網站的時候,為了瞭解程式碼的功能,我們可以通過JavaScript除錯工具設定斷點,阻止程式碼執行。進而分析斷點的執行環境,物件,變數等一系列有用的資訊,完成程式碼邏輯的解讀。

在JavaScript中,我們可以直接使用debugger指令,將程式碼斷在指定位置,舉個?

console.log('you can see me')
debugger
console.log('can you see me?')
複製程式碼

結果其實比較明顯,你可以看到第一行的輸出,但是執行到第二行時,程式碼被斷住,只有你手動繼續執行才能看到第三行的輸出。就是這個原理很多商業產品程式碼中會定義一個無線迴圈的debugger指令,它的目的是

  • 不停地打斷你,浪費時間
  • 不斷的產生不可回收的物件,佔據你的記憶體,造成記憶體洩漏,沒過多久瀏覽器就會卡頓,甚至可以跑滿你的cpu,除錯你是不用想了,能關掉頁面就已經不錯了

在這裡給大家舉一個簡單易懂的?

setTimeout(function(){
	while (true) {
		debugger
	}
},100)
複製程式碼

像這種情況我們怎麼應對那? google一圈之後發現普遍的解決方案是:

Deactivate breakpoint,那它能解決問題嗎?

看下圖就知道了。由於忽略了所有斷點,連你自己設定的都不放過(你的斷點沒有意義了),會繼續去執行debugger,建立物件,你的cpu會被跑滿,我在實踐中發現這種髮式不靠譜。抬走,下一個!

除錯js碰到迴圈斷點(debugger),應該怎麼做?

還有一招就是:禁止斷點 具體操作見下圖

除錯js碰到迴圈斷點(debugger),應該怎麼做?
我們就可以忽略它,可以繼續打其他的斷點,還是有效果的。但是這種方式其實是有弊端的,比如建立其他執行環境等,就沒辦法解決問題了,上一張這種噁心情況的圖。

除錯js碰到迴圈斷點(debugger),應該怎麼做?
像這樣的我能利用上面的方式能解決嗎? 能,要不也沒有這篇文章了,哈哈 但是一定要耐心 好 我們會到正題,具體怎麼解決那? 看呼叫棧,如圖

除錯js碰到迴圈斷點(debugger),應該怎麼做?
我們可以看到這段程式碼是在player.js中的0x51c762呼叫的,那我們需要看player.js中的0x51c762到底幹了什麼?好,沿著這個思路我們看一看_0x51c7626和呼叫它的地方

除錯js碰到迴圈斷點(debugger),應該怎麼做?
這程式碼看著讓人崩潰,這是寫的什麼東西啊!別急,分析一波,之所以能夠迴圈debugger肯定和這個setInterval相關,這個定時器中呼叫了_0x51c7626函式,說明debugger跟0x51c7626函式有關,那麼把他們幹掉試一下。具體方法是copy一份player.js,註釋掉如下程式碼

_0x51c762();
setInterval(function() {
    _0x51c762()
}, 0xfa0);
複製程式碼

用charles(我用的是這個,你可以用別的抓包工具)重定向到你做了修改的js檔案

除錯js碰到迴圈斷點(debugger),應該怎麼做?
然後再進行除錯的時候是不是發現這種建立新執行環境的迴圈debugger沒有了。啊 哈哈哈。其實每個網站做的方式可能不同,但是套路是不變的。 上面只是提到一個單純使用dubugger指令的反除錯方法,其實還有很多其他的方式,比如時間差異的方式

var timelimit = 50;
var open = false;
var starttime = new Date();
debugger;
if (new Date() - starttime > timelimit) {
    open = true;
   	//此處執行你的反除錯邏輯,比如刪除操作
    open = false;
}
複製程式碼

像這種我們怎麼去解決它? 其實很簡單,我們可以斷點,調大timelimit(比如timelimit = 1000000),輕鬆繞過。實際中可能還有其他判斷條件,我們只要斷點一次將它置成false,保證它不會進入debugger的條件語句就好了 希望能對大家有幫助

未經本人允許,不得轉載,文章有疏漏淺薄之處,請各位大神斧正

相關文章