Заметка задумывалась как продолжение предыдущей заметки о том, как собираем 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
, что-бы получить читаемый стек вызовов.