Заметка задумывалась как продолжение предыдущей заметки о том, как собираем C++ креши на различных платформах включая asm.js и wasm. По количеству материала, это тянет только на заметку, а не полноценную статью, да и нужно быть наркоманом, что бы делать нативный клиент на C++, а потом засовывать его в браузер.
Но! Мы недавно делали доклад об опыте использования wasm на cppconf. Оказалось, что наркоманов больше чем я думал, да и новость Beta for Qt for WebAssembly Technology Preview. Данная заметка может быть полезна, если вы захотите сделать отлов крешей в production окружении.
Под катом:
- отлов падений в asm.js и wasm;
- как выглядит стек вызовов в Safari, Firefox, Chrome.
Отлов падений С++ кода в asm.js и wasm.
Отлов происходит через глобальный обработчик window.onerror.
window.onerror = function(messageOrEvent, source, lineno, colno, error) { ... }
В asm.js сообщение об ошибке и стек вызовов передается в параметре messageOrEvent. В случае wasm в messageOrEvent причина, что-нибудь типа Error: Out of bounds memory access (evaluating 'dynCall(rawFunction, a1, a2, a3)'), RuntimeError: index out of bounds и т.д
А в error попадает стек вызовов.
Стек
Мы используем ключ --emit-symbol-map при компиляции, что минимизирует имена функций. После компиляции получаем так называемые файлы символов.
Так выглядит файл символов для asm.js:
ljd:___cxx_global_array_dtor_11639 YZb:___cxx_global_array_dtor_40_30909 Ya:_glClearStencil
Для wasm это номер функции и имя функции:
14:_glStencilFunc 15:_glUniformMatrix4fv 16:_emscripten_set_touchend_callback 17:_glGenRenderbuffers 18:_emscripten_set_webglcontextlost_callback 19:_glUniform2fv
Стек в разных браузерах выглядит по своему
Safari:
wasm function: 5960@[wasm code] wasm function: 5984@[wasm code] wasm function: 5981@[wasm code] wasm function: 1233@[wasm code] wasm function: 1232@[wasm code] wasm function: 34895@[wasm code] wasm function@[wasm code] dynCall_viii@[native code]
Firefox:
wasm-function[5960]@https://path_to_source wasm-function[5984]@https://path_to_source wasm-function[5981]@https://path_to_source wasm-function[1233]@https://path_to_source wasm-function[1232]@https://path_to_source wasm-function[34895]@https://path_to_source dynCall_viii_419@https://path_to_source
Chrome:
at wasm-function[2007]:11 at wasm-function[11257]:228 at wasm-function[11606]:479 at wasm-function[11604]:1726 at wasm-function[11819]:91 at wasm-function[9055]:274 at wasm-function[9052]:26 at wasm-function[2721]:92 at wasm-function[1302]:2523 at wasm-function[4946]:69
Chrome выдает не только номер функции 2007, но и смещение в ней 11. Так же chrome позволяет просматривать код в текстовом виде. На снимке экрана код 276 функции.

Это бывает полезно, например если выстрелил undefined behavior .
Остается только вытащить номера функций, сопоставить с функциями в файле, пропустить через abi::__cxa_demangle, что-бы получить читаемый стек вызовов.
