C++ креши в WebAssembly на разных браузерах

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

    Поддержать автора
    Поделиться публикацией

    Комментарии 0

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

    Самое читаемое