我正在嘗試從使用 Tracing Profiler 收集的日志資料中重建執行的 Javascript 函式(呼叫圖)的確切順序,特別是從“v8.cpu_profiler”類別中。
不幸的是,即使我以完全相同的方式與測驗 Web 應用程式互動,我獲得的節點(函式定義)和邊(函式呼叫)的數量也會隨著運行而波動。
目前,我使用 Puppeteer 提取跟蹤并與應用程式互動:
let browser = await puppeteer.launch({
headless: true,
userDataDir: userDataFolder,
args:[
`--disable-extensions`,
`--js-flags=--jitless --no-opt --predictable --no-concurrent-recompilation `] // disable chrome's optimizations
});
// Get the tab opened by default
let [page] = await browser.pages();
// Make sure to disable the cache
await page.setCacheEnabled(false);
// create cdp session
const cdp = await page.target().createCDPSession();
await cdp.send('Tracing.start', {
traceConfig: {
recordMode: 'recordContinuously',
includedCategories: ['disabled-by-default-v8.cpu_profiler'],
excludedCategories: ['*']
},
transferMode: 'ReturnAsStream'
});
await page.waitForTimeout(1000);
// Go to the page
await Promise.race([
page.goto(this.url, { waitUntil: ["load", "networkidle2"] }),
page.waitForTimeout("body"),
]);
// Wait to make sure that the page is fully loaded
await page.waitForTimeout(1000);
// dynamically interact with the webpage
await interact(page);
如您所見,我使用這些標志--jitless --no-opt --predictable --no-concurrent-recompilation來禁用我所知道的任何非確定性來源,但這仍然不夠。為什么會這樣?從理論上講,執行的功能完全相同,Tracing Profiler 應該非常精確。
是否有可能 v8 仍在幕后進行一些優化,如果是,我該如何禁用它們?
有沒有其他方法可以提取執行函式的確切順序?
uj5u.com熱心網友回復:
V8 有一個--trace標志,它給出了執行函式的確切順序。警告:它會產生大量輸出,因為典型網站上有很多函式呼叫。
函式呼叫順序是完全確定的。內部優化與此無關,因此沒有理由將其關閉。(想一想:如果優化改變了函式相互呼叫的順序,那將會破壞應用程式。無論引擎在內部做什么,都不能改變網站開發人員想要的行為。)
“Tracing Profiler”是一個基于樣本的分析器,因此在設計上是不確定的(不可能有一個標志來“關閉它”)。它使用每毫秒(或類似的時間間隔,我不確定確切的值)對主執行緒進行采樣的代碼執行緒。此時主執行緒到底在做什么在不同的運行之間會有所不同;它僅具有統計意義(例如,如果一個函式占用總時間的 X%,它將在大約 X% 的采樣滴答聲中表示)。
當然,JavaScript 應用程式可以有自己的非確定性來源:
if (Math.random() < 0.5) { foo(); } else { bar(); }將在不同的運行中創建不同的呼叫序列。還可以想象,JavaScript 會對滑鼠移動或其他用戶互動做出反應,這將非常難以準確復制。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/520748.html
