00
:
00
:
00
:
00
Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Debug e Profiling

Panoramica

Debuggare WebAssembly è più complesso rispetto a JavaScript, ma gli strumenti sono migliorati significativamente. Chrome DevTools, Firefox DevTools e strumenti specifici permettono di ispezionare, debuggare e profilare moduli Wasm.

Chrome DevTools

Visualizzare il Codice Wasm

Chrome può mostrare il codice WebAssembly Text (WAT) nei DevTools:

  1. Apri DevTools (F12)
  2. Vai nella tab Sources
  3. Trova il file .wasm nel pannello di navigazione
  4. Chrome mostra il codice WAT decompilato

Source Maps per Codice Sorgente

Con DWARF debug info, Chrome può mostrare il codice sorgente originale (C/C++/Rust) invece del WAT:

# Emscripten: compilare con debug info
emcc main.c -o main.wasm -g -gsource-map

# Rust: compilare con debug info
cargo build --target wasm32-unknown-unknown
# wasm-pack include automaticamente le source maps

Installa l’estensione C/C++ DevTools Support (DWARF) per Chrome per il supporto completo.

Breakpoint

Con le source maps abilitate puoi:

  • Impostare breakpoint nel codice C/C++/Rust originale
  • Fare step through riga per riga
  • Ispezionare variabili locali e i loro valori
  • Visualizzare lo stack trace completo

Ispezionare la Memoria

La linear memory di Wasm è ispezionabile:

  1. Nella tab Sources, trova il modulo Wasm
  2. Nel pannello Scope, espandi la sezione Memory
  3. Puoi visualizzare i byte raw della memoria lineare

Firefox DevTools

Firefox offre un supporto simile per il debug Wasm:

  • Visualizzazione del codice WAT
  • Breakpoint nel WAT
  • Ispezione della memoria lineare
  • Support per DWARF debug info (dalla versione 120+)

Strumenti da Linea di Comando

wasm-objdump

Parte di WABT (WebAssembly Binary Toolkit), mostra la struttura di un modulo:

# Installare wabt
npm install -g wabt

# Mostra le sezioni del modulo
wasm-objdump -h module.wasm

# Disassembla in WAT
wasm-objdump -d module.wasm

# Mostra import ed export
wasm-objdump -x module.wasm

wasm2wat e wat2wasm

Conversione tra formato binario e testuale:

# Da binario a testo (per ispezione)
wasm2wat module.wasm -o module.wat

# Da testo a binario (per test)
wat2wasm module.wat -o module.wasm

wasm-opt

Parte di Binaryen, ottimizza e analizza moduli Wasm:

# Ottimizzazione aggressiva
wasm-opt -O3 input.wasm -o output.wasm

# Ottimizzazione per dimensione
wasm-opt -Oz input.wasm -o output.wasm

# Mostra metriche
wasm-opt --metrics input.wasm

Profiling con Performance Tab

Chrome Performance Tab

  1. Apri DevTools → tab Performance
  2. Clicca Record e esegui l’operazione da profilare
  3. Nel flame chart, le funzioni Wasm appaiono come wasm-function[N]
  4. Con source maps, vedrai i nomi originali delle funzioni

Misurare i Tempi

// Misura il tempo di esecuzione nel codice JavaScript
console.time('wasm-operation');
const result = wasmModule.heavyComputation(data);
console.timeEnd('wasm-operation');

// Oppure con Performance API
const start = performance.now();
wasmModule.heavyComputation(data);
const elapsed = performance.now() - start;
console.log(`Operazione completata in ${elapsed.toFixed(2)}ms`);

Analisi Dimensione Bundle

Twiggy

Analizza quali funzioni occupano più spazio in un modulo Wasm:

# Installare twiggy (Rust)
cargo install twiggy

# Top funzioni per dimensione
twiggy top module.wasm

# Struttura ad albero dei dominatori
twiggy dominators module.wasm

# Percorsi dal root
twiggy paths module.wasm

wasm-opt --metrics

wasm-opt --metrics module.wasm
# Output:
# total
#   [funcs]      : 342
#   [memory-data]: 15234
#   [total]      : 89421

Debugging Comune

Errori di Memoria

Il problema più comune con Wasm è l’accesso alla memoria fuori dai limiti:

try {
  const result = wasmModule.exports.myFunction(ptr);
} catch (e) {
  if (e instanceof WebAssembly.RuntimeError) {
    console.error('Errore runtime Wasm:', e.message);
    // "memory access out of bounds"
    // "unreachable executed"
    // "integer overflow"
  }
}

Errori di Linking

try {
  const instance = await WebAssembly.instantiate(module, importObject);
} catch (e) {
  if (e instanceof WebAssembly.LinkError) {
    console.error('Errore di linking:', e.message);
    // Import mancante o tipo incompatibile
  }
}

Console Logging da Wasm

Per debuggare, puoi passare una funzione di log come import:

const importObject = {
  env: {
    log_i32: (value) => console.log('Wasm int:', value),
    log_f64: (value) => console.log('Wasm float:', value),
    log_string: (ptr, len) => {
      const bytes = new Uint8Array(memory.buffer, ptr, len);
      console.log('Wasm string:', new TextDecoder().decode(bytes));
    },
  },
};

Best Practice

  1. Compila con debug info durante lo sviluppo (-g flag) e rimuovilo in produzione
  2. Usa wasm-opt prima del deploy per ottimizzare dimensione e velocità
  3. Profila con dati realistici — i micro-benchmark possono essere fuorvianti
  4. Monitora la dimensione del bundle — un modulo Wasm grande rallenta il caricamento
  5. Testa su diversi browser — le performance possono variare tra V8 e SpiderMonkey
  6. Usa i try/catch attorno alle chiamate Wasm per gestire errori runtime