Tuesday, 24 November 2020

DOM Recording For Web Application Demos

To show off the power of our Pernosco debugger, we wanted many short demo videos of the application interface. Regular videos are relatively heavyweight and lossy; we wanted something more like Asciinema, but for our Web application, not just a terminal. So we created DOMRec, a DOM recorder.

The approach is surprisingly straightforward. To record a demo, we inject the DOMRec script into our application. DOMRec captures the current DOM state and uses a DOM Mutation Observer to record all DOM state changes with associated timestamps. To replay the demo, we create an iframe, fill it with the recorded initial DOM state, then replay the DOM state changes over time. Replay inserts links to the original stylesheets but doesn't load or execute the original scripts. (Of course it couldn't be quite that simple ... see below.)

The resulting demos are compact (most of ours are less than 100KB gzipped), work on almost any browser/device, and are pixel-perfect at any zoom level. DOMRec supports single-frame screenshots when dynamism is not required. We can't use browser HTML5 video controls but we implement play/pause/fullscreen buttons.

Capturing DOM state isn't quite enough because some rendering-relevant state isn't in the DOM. DOMRec logs mouse movement and click events and during replay, displays a fake mouse cursor and click effect. DOMRec tracks focus changes, and during replay sets "fake focus" classes on relevant DOM elements; our application style sheets check those classes in addition to the real :focus and :focus-within pseudoclasses. When necessary DOMRec creates a fake caret. DOMRec captures scroll offsets and makes a best-effort attempt to match scroll positions during recording and replay. Canvas drawing operations don't change the DOM and don't trigger events, so our application manually triggers a "didDrawCanvas" DOM event which DOMRec listens for. Sometimes the Pernosco client needs to trigger a style flush to get CSS transitions to work properly, which also needs to happen during replay, so we fire a special notification event for that too. It's a bit ad-hoc — we implemented just enough for needs, and no more — but it does at least handle Microsoft's Monaco editor correctly, which is pretty complicated.

DOMRec can record demos executed manually, but in practice our demos are scripted using Selenium so that we can rebuild the demo movie when our application interface has changed.

This kind of thing has certainly been built many times — see Inspectlet and its competitors — so when I first looked into this problem a few years ago I assumed I would find an open-source off-the-shelf solution. Unfortunately I couldn't find one that looked easy to consume. Now we're releasing DOMRec with an MIT license. To tell the truth, we're not trying hard to make DOMRec easy to consume, either; as noted above, some applications need to be tweaked to work with it, and this blog post is about all you're going to get in terms of documentation. Still, it's only 1200 lines of standalone Javascript so people may find it easier than starting from scratch.

Friday, 20 November 2020

Debugging With Screenshots In Pernosco

When debugging graphical applications it can be helpful to see what the application had on screen at a given point in time. A while back we added this feature to Pernosco.

This is nontrivial because in most record-and-replay debuggers the state of the display (e.g., the framebuffer) is not explicitly recorded. In rr for example, a typical application displays content by sending data to an X11 server, but the X11 server is not part of the recording.

Pernosco analyzes the data sent to the X11 server and reconstructs the updates to window state. Currently it only works for simple bitmap copies, but that's enough for Firefox, Chrome and many other modern applications, because the more complicated X drawing primitives aren't suitable for those applications and they do their complex drawing internally.

Pernosco doesn't just display the screenshots, it helps you debug with them. As shown in the demo, clicking on a screenshot shows a pixel-level zoomed-in view which lets you see the exact channel values in each pixel. Clicking on two screenshots highlights the pixels in them that are different. We know where the image data came from in memory, so when you click on a pixel we can trace the dataflow leading to that pixel and show you the exact moment(s) the pixel value was computed or copied. (These image debugging tools are generic and also available for debugging Firefox test failures.) Try it yourself!

Try Pernosco on your own code today!

Saturday, 14 November 2020

rr Repository Moved To Independent Organisation

For a long time, rr has not been a Mozilla project in practice, so we have worked with Mozilla to move it to an independent Github organization. The repository is now at https://github.com/rr-debugger/rr. Update your git remotes!

This gives us a bit more operational flexibility for the future because we don't need Mozilla to assist in making certain kinds of Github changes.

There have been no changes in intellectual property ownership. rr contributions made by Mozilla employees and contractors remain copyrighted by Mozilla. I will always be extremely grateful for the investment Mozilla made to create rr!

For now, the owners of the rr-debugger organisation will be me (Robert O'Callahan), Kyle Huey, and Keno Fischer (of Julia fame, who has been a prolific contributor to rr).

Tuesday, 10 November 2020

Pernosco Now Available For Individual Developers

We're pleased to announce that Pernosco is now available to individual developers!

Each Github account gets five free submissions. After that you can subscribe for 20 USD per month for 5 submissions per month or 30 USD for 5 "carry-over" submissions that don't expire. Workflow: make a recording with rr, then submit the recording to Pernosco with the pernosco-submit tool and credentials obtained from the Pernosco account page.

Pernosco supports x86-64 ELF binaries with DWARF debuginfo — e.g. C/C++/Rust — and V8 JS (in some configurations, e.g. Node, Chromium).

Experience how much better debugging can be, and contact us with any questions!

Update We've added a new "volume subscription plan" for individual users: 50 submissions per month for $50. This should make it easier to not think about rationing.

Sunday, 1 November 2020

Auckland Half Marathon 2020

I did the Auckland Half Marathon again this year. There were 4600 runners in the Half Marathon this year, a little down on the 5200 last year, but not bad given the COVID pandemic happening elsewhere and our borders being closed.

I did around 1:48. I pushed myself pretty hard this year and unlike some previous years I don't think I could realistically have pushed harder, but still didn't hit my personal best — and I'm a bit more sore than in previous years too. Some of that is no doubt just me getting older, but it may be partly due to residual tiredness having done the Pouakai Circuit last weekend. Also, it might be overall faster for me to walk rather than run up the Harbour Bridge, though it feels more satisfying to have run the whole way.

Anyway, despite my sore legs and feet, I am pleased I did my best.

Monday, 26 October 2020

Pouakai Circuit 2020

Last year's Pouakai Circuit tramp was good but I wanted to try again, hoping for better weather, and a friend had a day off and wanted to go on a short trip near Auckland, so I organised a group to walk the Pouakai Circuit again, Octobert 23-25 (Friday-Sunday).

Pouakai Hut is only 16 bunks and very popular, so I was worried it might be very full on Friday night (the day before Labour Weekend), so I decided to spend Friday night at Matekawa Hut, then walk around the mountain to Holly Hut for Saturday night, then either finish the circuit on Sunday or take the shorter track directly out to the visitor's centre. In the end we did finish the circuit, so we actually did "Pouakai Circuit plus Matekawa Hut".

On Friday we drove down from Auckland and had only a short walk to Matekawa Hut. The weather was a little bit drizzly but we had good views over the plains to the north and east of Mt Taranaki — including faint views of Mt Tongariro, Ngarahoe and Ruapehu —. Later in the evening the cloud over the mountain cleared and we got a good view of Mt Taranaki itself. We were the only people in the hut apart from one guy who walked up in the dark and arrived after we all were in bed!

On Saturday we got started reasonably early, leaving the hut around 8:20am even after cooking a decent breakfast. We walked up to Tahurangi Lodge, up "The Puffer", then west around the flank of the mountain to Holly Hut. Unfortunately the weather wasn't great, cloudy and drizzly and a bit windy too. Nevertheless the walk around the mountain was interesting, with some good views of waterfalls, lava cliffs and canyons in the mist. We got to Holly Hut in time for lunch and spent the rest of the afternoon watching people file in. As expected Holly Hut got pretty full; I think just about all the 32 bunks were taken, and there were several tents in the adjacent clearing. The weather improved a bit in the afternoon and we went out to the side track to Bell Falls, which is rather nice.

Yesterday we got going a bit earlier, around 8am. We crossed Ahukawakawa swamp and scooted up to Pouakai Hut in good time, taking only about 1.5 hours instead of the signposted 2.5 hours. The weather in the Pouakai tops was similar to the previous day — foggy, drizzly and a bit windy — so unfortunately we again didn't see much. Trampers at Pouakai Hut told us the hut had been incredibly full on Saturday night, more than 30 people in the 16 bunk hut, with people sleeping on floors, under bunks, etc. We pushed on to complete the circuit, walking over Henry Peak then down into the bush and out at the North Egmont road, with only a brief stop at Kaiauai Shelter for lunch, exiting around 2:30pm. The weather was overall significantly wetter than last year and the bush track yesterday afternoon was quite wet and muddy.

Overall the trip was a good workout and a lot of fun. We played Bang a fair bit, ate some good food and everyone said they enjoyed it despite the weather and the mud. I'm more determined than ever to go again when we can finally get some good weather and the great views that are possible!

Sunday, 11 October 2020

The Parable Of The Two Bus Drivers

Two bus drivers were driving along a dangerous mountain road. The first bus driver drove very fast in a hurry to get to town. Many times their bus scraped the guardrails and nearly plunged off the road, but the driver was lucky and each time managed to get the bus under control.

The second bus driver also wanted to get to town quickly, but was more afraid of plunging off the road, so drove a little slower. Their bus scraped the guardrails only a few times.

The second bus reached the town a few minutes after the first bus. Many passengers on the second bus complained: "if only you had driven faster, we could have arrived in town at the same time as the first bus. Next time we will choose the first bus driver."