Blog

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:

  1. Expose the full filesystem API
  2. 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!

code, how-toBobbie Chen