目前的道路
一年前,Chrome 宣布初步支援 這項工具針對 Chrome 開發人員工具中的 原生 WebAssembly 偵錯
我們展示了基本的步伐支援,並探討一些商機 使用 DWARF 資訊而非 來源對應日後開放使用:
- 解析變數名稱
- 美化排版
- 評估原文語言的運算式
- ...還有更多!
今天我們很高興向大家展示大家承諾使用的功能 Emscripten 和 Chrome 開發人員工具團隊的成長 尤其是 C 和 C++ 應用程式
正式開始前,別忘了這目前是 Beta 版 只有透過最新版所有工具 您必須自行承擔風險。如果遇到任何問題,請回報給 https://bugs.chromium.org/p/chromium/issues/entry?template=DevTools+issue.
讓我們先從上次相同的簡單的 C 範例開始:
#include <stdlib.h>
void assert_less(int x, int y) {
if (x >= y) {
abort();
}
}
int main() {
assert_less(10, 20);
assert_less(30, 20);
}
我們使用最新的 Emscripten 進行編譯
並傳遞 -g
標記 (與原始貼文相同) 以加入偵錯
每個 ACL 都由一或多個項目組成
而這些項目包含兩項資訊
emcc -g temp.c -o temp.html
現在,我們就能從 localhost HTTP 伺服器提供產生的網頁 (適用於 例如 serve) 請使用最新的 Chrome Canary 開啟應用程式。
這次,我們需要與 Chrome 整合的輔助擴充功能。 並協助解讀所有偵錯資訊 WebAssembly 檔案中編碼請前往以下網頁進行安裝: 連結:goo.gle/wasm-debugging-extension
建議您一併在開發人員工具中啟用 WebAssembly 偵錯功能 實驗。開啟 Chrome 開發人員工具,按一下位於⚙ 依序點選「開發人員工具」窗格右上角的「實驗」面板 然後勾選「WebAssembly Debugging:啟用 DWARF 支援」。
關閉「設定」後,開發人員工具會建議自行重新載入 開始套用設定吧一次性 設定。
現在我們可以返回來源面板,啟用暫停 例外狀況 (⏸ 圖示),然後勾選在偵測到的例外狀況時暫停和 請重新載入網頁。發生例外狀況時,開發人員工具應會暫停:
根據預設,它會停止在由 Emscripten 產生的黏合程式碼上,但會停留在
右圖顯示了「Call Stack」檢視畫面,代表
並可以前往先前叫用的 C 行
abort
:
現在,您查看「範圍」檢視畫面會顯示原始名稱
以及 C/C++ 程式碼中變數的值,您不再需要
瞭解 $localN
這類的破壞性名稱是什麼意思,以及它們與
所編寫的原始碼
這不僅適用於整數等原始值,也適用於複合值 例如結構、類別、陣列等!
支援豐富類型
一起來看看較複雜的範例。這個 我們將使用 Mandelbrot 碎石 以下 C++ 程式碼:
#include <SDL2/SDL.h>
#include <complex>
int main() {
// Init SDL.
int width = 600, height = 600;
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* window;
SDL_Renderer* renderer;
SDL_CreateWindowAndRenderer(width, height, SDL_WINDOW_OPENGL, &window,
&renderer);
// Generate a palette with random colors.
enum { MAX_ITER_COUNT = 256 };
SDL_Color palette[MAX_ITER_COUNT];
srand(time(0));
for (int i = 0; i < MAX_ITER_COUNT; ++i) {
palette[i] = {
.r = (uint8_t)rand(),
.g = (uint8_t)rand(),
.b = (uint8_t)rand(),
.a = 255,
};
}
// Calculate and draw the Mandelbrot set.
std::complex<double> center(0.5, 0.5);
double scale = 4.0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
std::complex<double> point((double)x / width, (double)y / height);
std::complex<double> c = (point - center) * scale;
std::complex<double> z(0, 0);
int i = 0;
for (; i < MAX_ITER_COUNT - 1; i++) {
z = z * z + c;
if (abs(z) > 2.0)
break;
}
SDL_Color color = palette[i];
SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, color.a);
SDL_RenderDrawPoint(renderer, x, y);
}
}
// Render everything we've drawn to the canvas.
SDL_RenderPresent(renderer);
// SDL_Quit();
}
如您所見 這個例子裡有 50 行程式碼 外部 API,像是 SDL 程式庫 圖形和複數 C++ 標準程式庫。
我會利用上述的 -g
旗標編譯程式碼,以便加入
偵錯資訊,然後要求 Emscripten 提供 SDL2
程式庫並允許任意大小的記憶體:
emcc -g mandelbrot.cc -o mandelbrot.html \ -s USE_SDL=2 \ -s ALLOW_MEMORY_GROWTH=1
透過瀏覽器造訪產生的網頁時,可以看到 一些隨機色彩的碎形形狀:
再次開啟開發人員工具時,可以看到原始 C++ 檔案。這個 然而,程式碼內都沒有錯誤 (太棒了!),所以我們要設定 在程式碼開頭加上一些中斷點
當我們重新載入網頁時,偵錯工具會直接在我們的 C++ 來源:
右側可以看到所有變數,但只有 width
和 height
目前已經初始化,所以並沒有太多
現在讓我們在 Mandelbrot 主要迴圈中設定另一個中斷點,然後繼續執行
目前,palette
已填入一些隨機的顏色。
我們可以同時展開陣列本身和
SDL_Color
結構並檢查其元件,以驗證是否
沒有問題 (例如,「Alpha 版」管道一律會
直到完全不透明度為止)。同樣地,我們也可以展開並查看
儲存在 center
變數中複數的虛構部分。
如果您想存取的深層巢狀屬性 前往「Scope」檢視畫面,您可以使用「Console」(控制台)。 以及評估與否!不過請注意,較複雜的 C++ 運算式不會 。
再繼續執行幾次,看看內部 x
如何
再次進入「Scope」檢視畫面,並且新增
在控制台中評估變數名稱
將滑鼠遊標懸停在原始碼中的變數上:
從這裡開始或逐步執行 C++ 陳述式,並觀察 其他變數也會發生變化:
好的,當有偵錯資訊可用時,上述功能就很實用,但 對於不是以偵錯功能建構的程式碼 有哪些選項?
原始 WebAssembly 偵錯
舉例來說,我們要求 Emscripten 為
與其自己從原始碼進行編譯,至少
因為偵錯工具目前無法尋找相關聯的來源。
讓我們再次一步步進入 SDL_RenderDrawColor
:
我們將返回原始 WebAssembly 偵錯服務。
這看起來有點恐怖,大多數網頁程式開發人員也不會 但有時您可能會想對 無論是否使用偵錯資訊 您無法控制的第三方程式庫 才會發生其中一種只發生在實際工作環境中的錯誤
有鑑於此,我們對基本功能 以及偵錯體驗
首先,如果您之前使用過原始 WebAssembly 偵錯功能
請注意,整個反組譯碼現在會顯示在單一檔案中
更猜測 Sources 項目 wasm-53834e3e/
wasm-53834e3e-7
可能對應的函式。
新建名稱產生配置
我們也改善了反組譯畫面中的名稱。先前看到的畫面 只是數字索引,而在函式中,則完全沒有名稱。
現在我們產生名稱的方法與其他拆解工具類似
WebAssembly 名稱部分的提示
匯入/匯出路徑,最後,如果其他連線失敗
這些值取決於項目的類型和索引,例如 $func123
。你可以
以剛才的螢幕擷取畫面為例
以及更易於理解的堆疊追蹤
沒有可用的類型資訊時,可能難以檢查 例如基元以外的任何值 視為一般整數,無法得知它們背後的內容 記憶體用量
記憶體檢查
先前您只能展開 WebAssembly 記憶體物件 (在「Scope」檢視畫面中以 env.memory
表示)
包括個別位元組這在一些簡單的情況下適用
更方便地擴充資料,同時禁止重新解讀資料
格式。我們新增了一項功能
這也適用於線性記憶體檢查器
如果您在 env.memory
上按一下滑鼠右鍵,應該會看到新的
名為「InspectMemory」的選項:
點擊完畢後,畫面會顯示記憶體檢查器, 您可以在十六進位和 ASCII 檢視中檢查 WebAssembly 記憶體, 然後前往特定地址 不同格式:
進階情境和注意事項
剖析 WebAssembly 程式碼
開啟開發人員工具後,WebAssembly 程式碼會變得「分層」為
以便啟用偵錯功能這個版本的速度明顯較慢
這表示您無法依賴 console.time
、performance.now
以及其他評估程式碼速度的方法
因為您得到的數據並不代表實際成效
。
請改用開發人員工具效能面板 就能完整執行程式碼 不同函式所花費時間的詳細分析:
或者,您也可以在 開發人員工具關閉後執行應用程式 檢查完成後再開啟即可檢查控制台。
我們日後將會改善剖析情境,但目前主要是 注意所有事項想進一步瞭解 WebAssembly 分層情境,請參閱 WebAssembly 編譯管道的說明文件。
在不同機器 (包括 Docker / 主機) 上建構及偵錯
在 Docker、虛擬機器或遠端建構伺服器上進行建構時 您可能會遇到來源檔案路徑 您用於建構作業的檔案系統路徑 Chrome 開發人員工具在此情況下,檔案會顯示在 來源面板,但無法載入。
為修正這個問題,我們在 C/C++ 擴充功能選項。您可以用它重新對應任意路徑 協助開發人員工具找到來源
舉例來說,如果主體機器上的專案位於路徑底下
C:\src\my_project
,但是在下列位置的 Docker 容器中建構:
該路徑以 /mnt/c/src/my_project
表示,
即可在偵錯期間將這些路徑指定為前置字串:
第一個相符的前置字元「wins」。如果您熟悉其他 C++
此選項與 set substitute-path
指令類似
或 LLDB 中的 target.source-map
設定
對最佳化的版本進行偵錯
與其他語言版本一樣,如要獲得最佳偵錯效果,必須 已停用。最佳化作業可能會將函式內嵌至另一個函式、重新排序 或者移除程式碼的某些部分, 可能混淆偵錯工具,因此您就是使用者。
即使您不介意更多偵錯體驗,仍希望
針對最佳化版本進行偵錯,那麼大部分最佳化作業都會以
但函式內嵌函式除外我們會設法解決
日後,請改用 -fno-inline
您在編譯任何 -O
層級最佳化時,請停用該功能,例如:
emcc -g temp.c -o temp.html \ -O3 -fno-inline
分隔偵錯資訊
偵錯資訊會保留許多與程式碼相關的詳細資料, 類型、變數、函式、範圍,以及任何可能 對偵錯工具有幫助因此,通常檔案大小通常比 程式碼本身
如要加快 WebAssembly 模組的載入和編譯速度,您可能需要
想將這個偵錯資訊拆分為另一個 WebAssembly
檔案。如要使用 Emscripten,請傳送 -gseparate-dwarf=…
旗標,
想要的檔案名稱:
emcc -g temp.c -o temp.html \ -gseparate-dwarf=temp.debug.wasm
在本範例中,主要應用程式只會儲存檔案名稱。
temp.debug.wasm
,輔助擴充功能將可找出並
會在您開啟開發人員工具時載入
結合上述的最佳化設定後, 甚至可用於推送幾乎最佳化的 然後在本機端檔案對它們進行偵錯。在本例中 我們還需要覆寫儲存的網址,以利擴充功能 找出側邊檔案,例如:
emcc -g temp.c -o temp.html \ -O3 -fno-inline \ -gseparate-dwarf=temp.debug.wasm \ -s SEPARATE_DWARF_URL=file://[local path to temp.debug.wasm]
未完待續...
太好了,那是很多新功能的誕生!
這些新整合讓 Chrome 開發人員工具變得可行 功能強大的偵錯工具,不僅適用於 JavaScript,也適用於 C 和 C++ 應用程式 , 並將其分享到共用的跨平台網路。
不過,我們的旅程尚未結束。可望 從這裡開始:
- 清除偵錯過程中的粗糙邊緣。
- 新增對自訂類型格式設定工具的支援。
- 我們正在努力改善 剖析。
- 新增程式碼涵蓋率支援功能,讓項目更容易找到 未使用的程式碼
- 改善對主控台評估作業中運算式的支援功能。
- 新增支援更多語言。
- …還有更多!
在此同時,請協助我們測試您專屬的程式碼,並回報發現的問題 問題 https://bugs.chromium.org/p/chromium/issues/entry?template=DevTools+issue.
下載預覽頻道
建議您使用 Chrome Canary、Dev 或 Beta 版做為預設的開發瀏覽器。透過這些預覽版本,您可以存取開發人員工具中的最新功能、測試最先進的網路平台 API,以及找出網站的問題,以免使用者發現問題。
與 Chrome 開發人員工具團隊聯絡
請使用下列選項,討論貼文中的新功能和異動,或與開發人員工具相關的其他事項。
- 歡迎透過 crbug.com 提出建議或意見。
- 使用「更多選項」 > 回報開發人員工具問題說明 >在開發人員工具中回報開發人員工具問題。
- 前往 @ChromeDevTools 張貼 Tweet。
- 歡迎在「開發人員工具」推出「最新消息」YouTube 影片或「開發人員工具秘訣」YouTube 影片留言。