Cómo depurar WebAssembly de C/C++

Sofia Emelianova
Sofia Emelianova

WebAssembly proporciona una forma de ejecutar, por ejemplo, código C/C++ en la Web a una velocidad casi nativa y junto con JavaScript. En este documento, se muestra cómo configurar y usar las Herramientas para desarrolladores de Chrome para depurar mejor esas aplicaciones.

Una vez que configures DevTools, podrás hacer lo siguiente:

  • Inspecciona tu código original en Sources > Editor.
  • Pausa la ejecución con puntos de interrupción de línea de código y revisa el código fuente C/C++ original, no el archivo binario .wasm compilado.

Además, mientras la campaña esté pausada, podrás hacer lo siguiente:

  • Coloca el cursor sobre las variables del archivo fuente original y consulta sus valores.
  • Comprende los nombres de las funciones en Pila de llamadas y las variables en Alcance.
  • Genera propiedades anidadas en profundidad y objetos complejos en la consola.
  • Inspecciona la memoria del objeto con el Inspector de memoria.

Configurar

Para habilitar la depuración de WebAssembly de C/C++ en DevTools, haz lo siguiente:

  1. Compila tu aplicación con la información de depuración de DWARF incluida. Ejecuta el compilador Emscripten más reciente y pásale la marca -g. Por ejemplo:

    emcc -g source.cc -o app.html
    

    Para obtener más información, consulta Cómo compilar proyectos con información de depuración.

  2. Instala la extensión de Chrome de compatibilidad con DevTools para C/C++ (DWARF).

Depurar

Con DevTools configurado, depura tu código:

  1. Abre DevTools para inspeccionar tu sitio web. En este instructivo, puedes probarlo en esta página de demostración, que se compiló con la marca -g obligatoria.
  2. De manera opcional, agrupa los archivos que creaste para facilitar la navegación. En Fuentes, marca Menú de tres puntos. > Página > Casilla de verificación. > Agrupar por autoría o implementación Experimental..
  3. Selecciona el archivo fuente original del árbol de archivos. En este caso: mandelbrot.cc.
  4. Para establecer un punto de interrupción de línea de código, haz clic en un número de línea en la columna a la izquierda del Editor, por ejemplo, en la línea 38.

    Un punto de interrupción de línea de código establecido en la línea 38.

  5. Vuelve a ejecutar el código. La ejecución se detiene antes de la línea con el punto de interrupción.

Mientras esté en pausa, prueba lo siguiente:

  • En Sources > Editor, coloca el cursor sobre una variable para ver su valor en una información sobre herramientas.

Es el valor de una variable en un cuadro de información.

  • En Sources > Call Stack, consulta los nombres de las funciones tal como aparecen en la fuente.

Es la función principal de la pila de llamadas.

  • En Sources > Scope, consulta las variables locales y globales, sus tipos y valores.

Panel de alcance con variables locales y sus valores

  • En Console, las variables y los objetos de salida a los que es difícil navegar en Alcance:

    • Variables anidadas en profundidad, por ejemplo, elementos indexados en grandes arrays
    • Objetos complejos, incluidos aquellos a los que puedes acceder con punteros (->). Expándelos para inspeccionarlos.

Una variable anidada y un objeto complejo expandidos en la consola.

  • En Fuentes > Alcance, haz clic en el ícono Memoria. para abrir el Inspector de memoria y, luego, inspecciona los bytes sin procesar de la memoria del objeto. Para obtener más información, consulta Inspección de memoria de WebAssembly.

Inspeccionar la memoria de una variable

Rendimiento del perfil

Si las herramientas para desarrolladores están configuradas y abiertas, el código que ejecuta Chrome no está optimizado. Está organizado en niveles para brindarte una mejor experiencia de depuración.

En este caso, no puedes confiar en console.time() y performance.now() en tu código para perfilar el rendimiento. En su lugar, usa el panel Rendimiento para generar perfiles.

Como alternativa, puedes ejecutar tu código de generación de perfiles sin abrir DevTools y, luego, abrirlo para inspeccionar los mensajes en la Consola.

Separa la información de depuración

Para acelerar la carga y, al mismo tiempo, tener una mejor experiencia de depuración, puedes dividir la información de depuración en un archivo .wasm independiente. Para obtener más información, consulta Cómo depurar WebAssembly más rápido.

Puedes conservar este archivo de forma local o alojarlo en un servidor independiente. Para hacerlo con Emscripten, pasa la marca -gseparate-dwarf=<filename> y especifica la ruta de acceso al archivo:

emcc -g source.cc -o app.html \
     -gseparate-dwarf=temp.debug.wasm \
     -s SEPARATE_DWARF_URL=[file://local/path/to/temp.debug.wasm] | [URL]

Compila y depura en diferentes máquinas

Si compilas en una máquina con un sistema operativo (contenedor, VM o servidor remoto) diferente del que se ejecuta Chrome, es posible que debas asignar manualmente las rutas de acceso de los archivos de depuración.

Por ejemplo, si tu proyecto está en C:\src\project de forma local, pero se compiló en un contenedor de Docker con la ruta de acceso /mnt/c/src/project, haz lo siguiente:

  1. Ve a chrome://extensions/, busca la extensión C/C++ DevTools Support (DWARF) y haz clic en Details > Extension options.
  2. Especifica las rutas de acceso de los archivos anteriores y los nuevos.

Rutas de acceso de archivos antiguas y nuevas especificadas

Más información

Consulta el blog de ingeniería de Chrome DevTools para obtener más información sobre la depuración de WebAssembly: