Sign in Join
Wiki copytemporary

WebAssembly/Debugging: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: WebAssembly/Debugging

OldNewLine
1+Free Pascal can now create WebAssembly binaries with DWARF debug info. This allows debugging WebAssembly applications.
2+
3+## Debug info
4+
5+### DWARF
6+
7+Free Pascal for WebAssembly generates debug info that follows the [WebAssembly DWARF](<https://yurydelendik.github.io/webassembly-dwarf/>) specification.
8+
9+Using the _-g_ compiler option enables debug info generation. Due to limitations of the LLVM assembler and linker, this only works with FPC's internal assembler and linker, so make sure you're not compiling with _-a_ or _-Xe_.
10+
11+### Name section
12+
13+Free Pascal now also produces a [name section](<https://webassembly.github.io/spec/core/appendix/custom.html#name-section>) in the WebAssembly binary. This is a custom section, that adds function names to all the functions inside the module. This is very limited information, compared to DWARF, but is still helpful, because there are more tools that support it. The integrated debuggers in Mozilla Firefox and Google Chrome support that info and show the function names in the assembly level view of the module.
14+
15+### Source maps
16+
17+Source maps are JSON files that have been used traditionally for mapping generated (or minified) JavaScript files to their source. In principle, they are not a good fit for WebAssembly, which uses a binary format, and they are less powerful, compared to DWARF, because they only provide mapping to the source, without any extra information for examining variables and types. However, they're still useful as a stop gap solution, because they're widely supported by browser debuggers and some browsers (like Mozilla Firefox) still haven't implemented DWARF support.
18+
19+Free Pascal doesn't support generating source maps directly, however there are third party tools that allow generating a source map from the embedded DWARF debug info. One such tool that has been tested and known to work is [wasm2map](<https://github.com/mtolmacs/wasm2map>).
20+
21+Example usage:
22+```
23+cargo-wasm2map wasm2map --patch --base-url <http://localhost:8080> --bundle-sources myproject.wasm
24+```
25+
26+This will produce a file _myproject.wasm.map_.
27+
28+The _\--patch_ option embeds a link to the source map file inside the .wasm binary, so that browsers know where to find it. The _-base-url_ option specifies the prefix to the location of the map file. In this example, the location embedded in the .wasm file will be _<http://localhost:8080/myproject.wasm.map>_
29+
30+The _\--bundle-sources_ embeds the source files inside the .map file. Without this option, you would need to host your sources on the same http server (and recreate the original directory tree), where you host the source map.
31+
32+## Debugging
33+
34+### Debugging with Chrome/Chromium
35+
36+Chrome has a plugin for debugging C/C++ applications, called [C/C++ DevTools Support (DWARF)](<https://chromewebstore.google.com/detail/C%2FC++%20DevTools%20Support%20%28DWARF%29/pdcpmagijalfljmkmjngeonclgbbannb>). It works with Free Pascal as well. It allows setting breakpoints, stepping inside the program, and showing local and global variables, as well as function parameters of various types. Note that the plugin is in BETA, and is designed for C and C++, so it may not support all Pascal types.
37+
38+Here's a screenshot of a debugging session of a Pascal program in Chromium: [![Screenshot from 2024-09-21 10-57-17.png](/wiki-images/a/af/Screenshot_from_2024-09-21_10-57-17.png)](</File:Screenshot_from_2024-09-21_10-57-17.png>)
39+
40+### Debugging with Wasmtime
41+
42+Wasmtime supports debugging WebAssembly programs with gdb or lldb. Even though these debuggers don't support WebAssembly directly, debugging becomes possible, because Wasmtime performs JIT compilation of the WebAssembly bytecode to native code, and it also (optionally) translates the DWARF debug info, so that native debuggers can work with it.
43+
44+#### Using GDB
45+
46+To enable the debugger support and run your program inside gdb, use:
47+```
48+gdb --args wasmtime run -D debug-info -O opt-level=0 foo.wasm
49+```
50+
51+Note that running the program inside the debugger will not enter the Pascal code immediately. First, it'll run Wasmtime's code that JIT compiles the program. To skip that, you need to set a breakpoint somewhere in the Pascal code.
52+
53+##### Setting a breakpoint
54+
55+Generally, you can set this breakpoint in one of two ways:
56+
57+###### in the Pascal code directly
58+
59+To do this, type at the gdb command prompt:
60+```
61+break magic.pp:81
62+```
63+
64+This will add a breakpoint in magic.pp, line 81. Since the DWARF debug info for the WebAssembly program hasn't been transformed, yet, you get this prompt, because gdb doesn't know about the Pascal source, yet:
65+```
66+No symbol table is loaded. Use the "file" command.
67+ Make breakpoint pending on future shared library load? (y or [n])
68+```
69+
70+Answer _yes_ to this prompt. Then you get:
71+```
72+Breakpoint 1 (magic.pp:81) pending.
73+```
74+
75+After that, type _run_ at the gdb prompt, and if everything worked well, you should hit your Pascal breakpoint:
76+```
77+Thread 1 "wasmtime" hit Breakpoint 1, main () at magic.pp:81
78+ 81 size:=3;
79+ (gdb)
80+```
81+
82+Screenshots from a debug session, initiated this way:
83+
84+[![Screenshot from 2024-09-21 10-46-44.png](/wiki-images/f/fc/Screenshot_from_2024-09-21_10-46-44.png)](</File:Screenshot_from_2024-09-21_10-46-44.png>)
85+
86+[![Screenshot from 2024-09-21 10-51-50.png](/wiki-images/a/ae/Screenshot_from_2024-09-21_10-51-50.png)](</File:Screenshot_from_2024-09-21_10-51-50.png>)
87+
88+###### on entry of the main program
89+
90+You can also set a breakpoint to the main() function. The only detail you need to know is that, you will hit main() twice. First time it'll be Wasmtime's main. The second main() will be the Pascal main program. So, use the following commands:
91+```
92+break main
93+ run
94+ continue
95+```
96+
97+At this point, if everything is ok, you should be inside the first line of your Pascal main program.
98+
99+#### Using LLDB
100+
101+To start a debugging session with LLDB, use:
102+```
103+lldb -- wasmtime run -D debug-info -O opt-level=0 foo.wasm
104+```
105+
106+## See Also
107+
108+ * [[WebAssembly]]
109+
110+---
111+*From the Free Pascal wiki, page "WebAssembly/Debugging", as the Internet Archive kept it on 2025-03-14, last changed on 2024-10-05. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history