How to debug WebAssembly filesystem access
Today, I spent some time debugging access to the WebAssembly virtual filesystem with Emscripten and wanted to share a trick I found helpful.
It basically consists of two parts:
- Expose the full filesystem API
- Use it to check the directory structure and file contents
Normally, only a few of the WebAssembly filesystem APIs are exposed, which isn't useful for inspecting actual files.
Using the emcc
option -s 'EXPORTED_RUNTIME_METHODS=["FS"]
, we can expose all of them as the FS
attribute on Module
.
This lets us do things like this:
>> Module.FS.root // represents the root path
Object {
contents: {
dev: Object { id: 5, name: "dev", mode: 16895, … }
home: Object { id: 3, name: "home", mode: 16895, … }
proc: Object { id: 13, name: "proc", mode: 16895, … }
tmp: Object { id: 2, name: "tmp", mode: 16895, … }
wasmfiles: Object { id: 17, name: "wasmfiles", mode: 16895, … }
}
// a bunch more fields: like parent: {…}, mount: {…}, mounted: null, id: 1, etc.
}
Then we can dig into an actual file's contents by traversing the object:
>> myfile = Module.FS.root.contents
.wasmfiles.contents
.anotherdir.contents
["my-file.txt"].contents
Uint8Array(123) [ 73, 110, 32, 116, 104, 101, 32, 98, 101, 103, … ]
And then decode its contents to a string:
>> new TextDecoder().decode(myfile)
"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."
When I did this to the actual code I was debugging, I found all of the virtual files, instead of containing numeric data, instead started with <!DOCTYPE html>
and continued into Website created with create-react-app
.
Webpack strikes again!
I fixed it by moving the .data
file into the public
folder.
That made me realize my previous create-react-app demo repo could also benefit from using public
.
Previously it used SINGLE_FILE
to inline the .wasm
file, which causes bundle sizes to be larger due to base64 encoding.
I updated the demo repo with the new and improved approach now!
Thanks Evangelos for reaching out to me with your example code, which led to all of this!