Category Archives: Other

How I live-stream programming

I’ve been live-streaming myself doing operating systems programming every week for 6 months now. This is not meant to be a comprehensive guide on streaming, just an overview of how I do it.

The bare basics

I stream to Youtube using OBS. I use Youtube because:

  • It automatically archives the streams indefinitely to your channel by default. (Twitch only keeps the video for a limited time IIRC).
  • It exposes you to all of Youtube for potential viewership.

I tried Twitch once but didn’t get many viewers, so I stopped trying there.

A bit more (chat widget, alert boxes, chatbot)

I use Streamlabs’ free plan for my Chat Widget, Alert Boxes, and Chatbot. It works very well for a free offering and these add some more flair and professionalism to your stream.

  • Chat Widget: The messages in the chat are rendered directly into the stream video. The chat is an important part of the streaming experience, and it would be a shame to lose those messages. This ensure they are at least captured in the video.
  • Alert Boxes: These are visual effects that show in the stream when someone subscribes or does other actions.
  • Chatbot: I have a few chatbot commands for answering common questions about my tools, discord, or recommended sources. The chatbot is also useful for moderating the chat and e.g. restricting offensive language.

After using a basic OBS setup for a while, I customized it with a text box at the top that gives viewers a quick sense of what I do (“Streaming OS/Kernel Dev, Assembly & Low Level Programming”), the topic of today’s stream, and a friendly invitation to engage in the chat.

Misc tips

I used this plugin for background removal for that streamer green-screen effect (without a green-screen). It’s quality is just ok. I eventually stopped using it and just show my background.

  • After streaming to Youtube, be careful to not use their built in trimming tools because this removes the chat replay from the video. I used to press stream, then trim the beginning, but now I press stream and immediately start to preserve the native Youtube replay.
  • Resolution — Increase your screen resolution so people can read the text more easily. On my monitor, I reduce the resolution to 720p and live with the fact that it’s comically big for me when I stream.
  • Music — I use a 3 hour LoFi hip hop video on Youtube that explicitly claims to be No Copyright. I have OBS set to do a macOS capture which records audio. I then play it, and actually mute my laptop so I don’t hear it (it distracts me when programming) but it gets recorded in the stream.
  • Multi-streaming — You can multi-stream to Youtube and Twitch with paid Streamlabs, but there are other ways to do it, apparently even including using ffmpeg locally.
  • Youtube Thumbnails — I use CapCut, which is perfect for this. I took a screenshot of one of my streams, loaded it in CapCut, then overlay a few text objects and images on top. CapCut paid version also conveniently can remove backgrounds from people and give a colored border for that authentic Youtuber effect.

Do you need to learn how to implement a red-black tree?

Experiment: Categories for my posts

I’m trying something new. I added WordPress tags for higher level categories of content that cut across the typical tags:

  • Deep Dive: Longer, more detailed posts that require significant research. Very expensive to produce.
  • Tech: Normal technical blog post. More polished than Lab Notes, less researched than Deep Dive.
  • Lab Notes: Rough notes, typically technical, usually bullet points about some topic.
  • Essay: Nonfiction writing, usually nontechnical.
  • Micropost: Tiny, short thought.

I hope that by categorizing things this way and acknowledging that this blog is a collection of different art forms (that appear similar because they’re all writing), I’ll be more comfortable publishing publicly. For a while I was scared to publish because I don’t have as much time for deep dives as before, which is what people seemed to really like, but acknowledging these different categories and specifically calling out a shorter, rougher, less polished piece as such takes the pressure off of publishing it.

Why do computers reboot multiple times during an update?

Have you every updated your operating system and your computer rebooted multiple times during the process? Why does this happen? Why isn’t one reboot enough?

In general, if you have some running computer system that wants to upgrade itself, it’s easiest to download the new version, exit, and simply restart from scratch.

This is why you usually have to reboot for OS updates to take effect. On a different level, this is also why you usually have to reboot applications for their software updates to be applied.

The alternative to rebooting is hot swapping: the running program dynamically swapping itself out with the new one — while staying running the entire time. This is harder than rebooting and requires the developer to actually write code to implement this. A reboot-based update generally does not require much code beyond downloading the artifact into the place it will be looked for the next time things start.

If you opt for dynamic swapping, you need to make sure that the update applies cleanly and absolutely in memory — such that there are no lingering pieces of state from the old software lurking. You don’t want to be running half old software, half new software. (Or have old data in memory, half new data)

In general, this is not a problem if you reboot. Reboots start from a clean slate, so you can be sure that after reboot, you’re running with 100% the new software, 0% the old.1

These fundamental principles apply to any update on any kind of system: an application, its dependencies, an operating system (including core userspace libraries), or firmware running on a device.


So why would a computer reboot multiple times during an update?

It’s probably because it has updates A, B, and C to make, and they each require a reboot to take effect.

If there are blocking dependencies between then (C requires B first, which requires A first), there’s no way around doing a reboot after applying each.

If there are no dependencies, then it might be technically feasible to try to apply them all at the same time, and have them all apply together on the next reboot. But even so, such mass changes with multiple things updating all at once can be riskier. So it might still be safest to sacrifice update speed and update in a slower, more controlled manner, one update & reboot at a time.

For example:

  • There is a migration to a newer, fancier update server infrastructure
  • Using this new infra requires a newer version of a core library that is in use on the running old system
  • One last update is pushed to the old infrastructure which updates the core library. Reboot once.
  • Now the system can fetch a new update ZZ that’s sitting in the new infrastructure, using its new library support. Reboot again.
  • And then maybe the version ZZ of the software has some init code that downloads a firmware update for hardware component that ZZ needs to run. This update is incompatible with the previous version and is only applied once ZZ is confirmed to be present and working. Download the firmware update and reboot a third time.

One concrete technique I’m aware of that results in multiple boots is a disk image space optimization.

When building a disk image for a device, it’s common to include a data partition for user data which is separate from the system partition. In real use, the data partition will likely be very large, but when initially building a fresh image, the data partition will be all zeros. This is wasteful and makes the disk image occupy must more space than necessary, which slows down file transfers.

An optimization would be to build the disk image with a smaller data partition — just as big as necessary to hold pre-existing files on the partition. Then on the first boot, resize the partition to occupy the full available space. An easy way to apply that change to the system is to then reboot.


* The exception is persistent state. If your system leaves persistent state on disk or elsewhere, you need to be careful that those artifacts are either compatible with the new system, or migrated.


More: https://www.quora.com/Why-does-a-computer-restart-several-times-during-a-Windows-update


Update, April 2024: Another reason: the update signing keys were updated. To perform this transition one update needs to be release that embeds the new public key, but is still signed with the old private key, then future releases can be made signed with the new private key.

What’s with the name?

I chose “offlinemark” as a handle for a few reasons:

  • I didn’t want to use my real full name as the handle because of privacy and because I don’t consider my last name a 100% stable API. Ideally this username would last a long time.
  • I like adjectives as usernames, but also including my first name makes it feel a bit personal.
  • It’s highly unique. There’s a strong chance I can always get this username.
  • It’s a bit techy, which is on brand.
  • Aesthetics. I dislike numbers in usernames. I like the visual appearance of the text (all on one line, no underhanging characters).
  • It’s an aspirational reminder. A lot of the best things in life are offline.
  • It appeals to my ironic and quirky sense of humor.
  • And, it will be true one day.

Pick an impressive project, then checkout to the first commit

A takeaway I often get from exploit writeups

I get asked why I’m into C++ and not Rust.

I get asked why I’m into C++ and not Rust.

Above all, it’s pragmatic. C++ is simply what’s used for the work I aspire to do, and I don’t have time for both.

Beyond that, I still think there’s at least one reason to learn C++ today: out of respect for where it’s gotten us. A lot of lessons to learn from something that powers the world, flaws and all.

And when you do learn Rust, you’ll understand it better. The C++ context will give you a deeper & more intuitive appreciation for why it’s like it is. 

Rust wouldn’t be what it is without C++. 🤝

tweet: