有没有办法改变堆栈跟踪中函数的路径?
Is there a way to change the path of a function in the stack trace?
假设我们有一个函数,它生成一个错误抛出函数:
function p(){
function q(){
throw new Error();
}
q();
}
p();
堆栈跟踪看起来像这样:
Error: x
at path:3:8
at q (path:5:4)
at p (path:7:1)
那么 p
函数将如下所示:
如何更改 p
以获得如下所示的堆栈跟踪?
Error: x
at something-else:12:12
at q (something-else:34:34)
at p (path:7:1)
我不控制这些文件,因为我们现在通过客户端代码使用捆绑包,所以将 q
放入单独的文件中不是解决方案。据我所知我问的是不可能的,但也许有人比我更了解 js。 :D
如果您想知道这里的目标是什么,我想告诉堆栈解析器路径在帧字符串中的位置。
我找到了多种方法:
1.) 数据 URI
我从一种数据 URI 方法开始,它没有得到广泛支持,但总比没有好:
function report(e){
console.log(e.stack);
}
window.onload = function (){
var s = document.createElement("script");
s.setAttribute("src", "data:text/html,try {throw new Error;}catch(e){report(e);}");
var body = document.getElementsByTagName("body")[0];
body.appendChild(s);
}
它适用于除 IE 之外的最近的主要桌面浏览器,它不允许通过脚本标记的数据 URI。它记录以下堆栈:
Error
at data:text/html,try {throw new Error;}catch(e){report(e);}:1:12
2.) IFrame
之后我想了想,如果这适用于数据 URI,那么它可能也适用于 iframe,所以我想到了这个:
function report(e){
console.log(e.stack);
}
window.onload = function (){
var i = document.createElement("iframe");
i.setAttribute("style", "display:none");
var body = document.getElementsByTagName("body")[0];
body.appendChild(i);
var idoc = i.contentDocument || i.contentWindow.document;
var ibody = idoc.getElementsByTagName("body")[0];
var s = document.createElement("script");
s.innerHTML="try {throw new Error;}catch(e){parent.report(e);}";
ibody.appendChild(s);
}
它记录以下堆栈:
FF:
@about:blank:1:12
window.onload@file:///C:/Users/inf3rno/Downloads/x.html:18:2
Chrome 和歌剧:
Error
at <anonymous>:1:12
IE11
Error
at Global code (Unknown script code:1:6)
at window.onload (file:///C:/Users/inf3rno/Downloads/x.html:17:2)
我们可以简单地通过添加一个函数调用来添加另一个框架:
s.innerHTML="function a(){\ntry {\nthrow new Error;\n}catch(e){\nparent.report(e);\n}\n};\n a();";
在 IE 中记录以下内容:
Error
at a (Unknown script code:3:1)
at Global code (Unknown script code:8:2)
at window.onload (file:///C:/Users/inf3rno/Downloads/x.html:19:2)
所以我们可以将 at a (Unknown script code:3:1)
与在父 window 中调用的类似函数进行比较: at a (file:///C:/Users/inf3rno/Downloads/x.html:13:1)
并且相对容易找到路径。
3.) 评估
使用 eval 是一种有趣的方法。它在 IE 中给出了类似 at a (eval code:3:1)
的东西,而在其他浏览器和节点中它给出了一个复杂的嵌套位置:at a (eval at window.onload (x.html:21), <anonymous>:3:7)
或 at a (eval at <anonymous> (repl:1:1), <anonymous>:1:20)
。我认为这是最好的方法,因为它不需要 DOM 并且即使在严格模式下也适用于每个 js 环境。
假设我们有一个函数,它生成一个错误抛出函数:
function p(){
function q(){
throw new Error();
}
q();
}
p();
堆栈跟踪看起来像这样:
Error: x
at path:3:8
at q (path:5:4)
at p (path:7:1)
那么 p
函数将如下所示:
如何更改 p
以获得如下所示的堆栈跟踪?
Error: x
at something-else:12:12
at q (something-else:34:34)
at p (path:7:1)
我不控制这些文件,因为我们现在通过客户端代码使用捆绑包,所以将 q
放入单独的文件中不是解决方案。据我所知我问的是不可能的,但也许有人比我更了解 js。 :D
如果您想知道这里的目标是什么,我想告诉堆栈解析器路径在帧字符串中的位置。
我找到了多种方法:
1.) 数据 URI
我从一种数据 URI 方法开始,它没有得到广泛支持,但总比没有好:
function report(e){
console.log(e.stack);
}
window.onload = function (){
var s = document.createElement("script");
s.setAttribute("src", "data:text/html,try {throw new Error;}catch(e){report(e);}");
var body = document.getElementsByTagName("body")[0];
body.appendChild(s);
}
它适用于除 IE 之外的最近的主要桌面浏览器,它不允许通过脚本标记的数据 URI。它记录以下堆栈:
Error
at data:text/html,try {throw new Error;}catch(e){report(e);}:1:12
2.) IFrame
之后我想了想,如果这适用于数据 URI,那么它可能也适用于 iframe,所以我想到了这个:
function report(e){
console.log(e.stack);
}
window.onload = function (){
var i = document.createElement("iframe");
i.setAttribute("style", "display:none");
var body = document.getElementsByTagName("body")[0];
body.appendChild(i);
var idoc = i.contentDocument || i.contentWindow.document;
var ibody = idoc.getElementsByTagName("body")[0];
var s = document.createElement("script");
s.innerHTML="try {throw new Error;}catch(e){parent.report(e);}";
ibody.appendChild(s);
}
它记录以下堆栈:
FF:
@about:blank:1:12
window.onload@file:///C:/Users/inf3rno/Downloads/x.html:18:2
Chrome 和歌剧:
Error
at <anonymous>:1:12
IE11
Error
at Global code (Unknown script code:1:6)
at window.onload (file:///C:/Users/inf3rno/Downloads/x.html:17:2)
我们可以简单地通过添加一个函数调用来添加另一个框架:
s.innerHTML="function a(){\ntry {\nthrow new Error;\n}catch(e){\nparent.report(e);\n}\n};\n a();";
在 IE 中记录以下内容:
Error
at a (Unknown script code:3:1)
at Global code (Unknown script code:8:2)
at window.onload (file:///C:/Users/inf3rno/Downloads/x.html:19:2)
所以我们可以将 at a (Unknown script code:3:1)
与在父 window 中调用的类似函数进行比较: at a (file:///C:/Users/inf3rno/Downloads/x.html:13:1)
并且相对容易找到路径。
3.) 评估
使用 eval 是一种有趣的方法。它在 IE 中给出了类似 at a (eval code:3:1)
的东西,而在其他浏览器和节点中它给出了一个复杂的嵌套位置:at a (eval at window.onload (x.html:21), <anonymous>:3:7)
或 at a (eval at <anonymous> (repl:1:1), <anonymous>:1:20)
。我认为这是最好的方法,因为它不需要 DOM 并且即使在严格模式下也适用于每个 js 环境。