无限debug
原理
1、定时器原理
利用setInterval或setTimeout打开了另一个线程并制定相应的时间,来执行debugger
setInterval(function(){debugger;}, 1000)
setTimeout(function b(){debugger;setTimeout(b, 1000);}, 1000)
2、递归无限循环
function registerRecursion(){
function a(){debugger;b()}
function b(){a()}
b()
}
registerRecursion()
解决方案
1、清除计时器:
使用clearInterval()删除所有的定时器。根据setInterval,线程id递增。来清除
但是有个缺点,会误伤系统本身逻辑。不建议使用
//版本1,过程中出现setInterval,无法清除
function clearAllInverval(){
var id = setInterval(function(){}, 0)
while(id > 0){
clearInterval(id)
id--
}
}
clearAllInverval()
//版本2,过程中出现setInterval,彻底清除
var gid = setInterval(clearAllInverval, 1000)
function clearAllInverval(){
var id = setInterval(function(){}, 0)
while(id > 0){
if (id != gid){
clearInterval(id)
};
id--
console.log(id)
}
}
2、F12,在debugger地方使用“never pause here”
比较笨的方法,有时候不一定生效,因为无限调用导致内存崩掉卡死
3、hook:
3.1、hook 定时器函数
// hook 定时器函数 替换debugger
_setInterval = setInterval
setInterval = function setInterval(code, time){
code = code.toString().replace(/debugger/, "").replace(/function ()/, "return function ()")
ssssa = new Function("return function(){ console.log(121212) }")
// ssssa.apply(this, arguments);
return _setInterval(ssssa() , time)
}
3.2、通过hook Function原型链
//
Function.prototype.before = function(beforefn){
let that = this
return function(){
arguments[0] = arguments[0].toString().replace(/debugger/, "").replace(/function()/, "function xxx")
beforefn.apply(this, arguments)
return that.apply(this, arguments)
}
}
Function.prototype.after = function(afterfn){
let that = this
return function(){
let ret = that.apply(this, arguments)
afterfn.apply(this, [ret])
return ret
}
}
//debugger
setInterval = setInterval.before(function(){
console.log('arguments', arguments)
}).after(function(result){
console.log('result', result)
})
setInterval(function(){
debugger
}, 1000)
function ddd(){
return 1+2
}
//debugger
ddd = ddd.before(function(){
console.log('arguments', arguments)
}).after(function(result){
console.log('result', result)
})
ddd(1,2)