unrelenting.technology

Ported the Firefox Profiler to FreeBSD in order to investigate why WebRender has some jank when scrolling some walls of text on my 4K/HiDPI setup.

The profiler code initially looked somewhat scary: some Google Breakpad code is used, a custom stack unwinder called LUL is used on Linux (which also partially derived from Breakpad code)…

Initially, I got it working with “pre-symbolication” (an option to build the goblin ELF parser into Firefox for this purpose) only, ifdef’ing any Breakpad code out.

Turns out:

  • the only part of Breakpad used is extracting build IDs from shared objects (and in fact the “base profiler”, a copy (for now) of the Gecko profiler used for profiling during the early startup phase, just copied all the relevant code);
  • devel/breakpad was there in FreeBSD Ports (but expires in like three days!), and its patches showed that it’s really trivial to get all it working.

So I got the main symbolication system working. Which, it turns out, runs WebAssembly-compiled goblin in a web worker! Fun stuff. Requires stripping libxul for now tho.

In the end, the patch turned out to be mostly just ifdef’s! The only meaningful parts are: thr_self/thr_kill2 instead of gettid/tgkill, supporting the different mcontext structs, and (for the pre-symbolication code path) ignoring symbol names returned by dladdr because they’re hilariously bad.

BTW, earlier in the dev-tools-on-FreeBSD space: heaptrack! I even used it to find a real memory leak in Wayfire.