As you are well-aware, Windows is a closed-source operating system. That, however, does not mean that it is opaque. In fact, it feels quite the opposite in many areas, which might be a surprise to you—especially if you develop on/for open-source operating systems.
A blog on operating systems, programming languages, testing, build systems, my own software projects and even personal productivity. Specifics include FreeBSD, Linux, Rust, Bazel and EndBASIC.
To understand why that might be, put yourself in the shoes of a Windows engineer and consider how Windows must be extensible in various ways: kernel-level drivers, File Manager extensions, PowerShell cmdlets… you name it. If you start with the premise that you must support these scenarios from a closed-source OS, you will have to design the product in ways that are not common in open source systems. For example:
- Supporting loadable binary plugins will be a requirement for extensibility because people can’t just edit the code.
- Having clear API documentation will be a must because people won’t be able guess what calls are available and how they behave from their implementation.
- Having backwards binary compatibility will be important because users won’t be able to recompile whichever piece of software they are using against newer versions of the system.
Take drivers as a thought exercise. Drivers are a gnarly thing to develop because they run inside the kernel, interact directly with the hardware and the kernel’s interfaces, and any error in kernel-level cannot be easily debugged from userland. Or can it? I’ve been reading through the “Advanced Windows Debugging” and “Windows Internals, 5th edition” books (haven’t made it very far in either though) and it’s impressive how much you can learn about the system without actually having its source code.
Speaking of debugging and internals, one thing that “shocked” me when joining Microsoft is how much emphasis is put on using a debugger and how incredibly good some people are at debugging extremely subtle bugs purely from a crash dump. At Google, using a debugger was quite a rarity! And it’s equally impressive how good the debugging features are: Time Travel Debugging is mind-blowing.
The open source approach
I can’t avoid but compare this to Linux or any of the BSDs. I don’t think any of these systems reach this level of… integrability? I know it sounds like a strange thing to say, but relying on their source code for interoperability purposes is both a blessing and a curse.
It is a blessing because these systems can be simpler by assuming that people can “just edit the source and recompile”. But it is a curse because many times you have to recompile things (Nvidia Linux drivers, anyone?) and is what makes it almost impossible to have commercial software running on these platforms. Whether this is a good or bad thing from a “freedom” perspective is an orthogonal topic.
Mind you: one of the reasons I liked the BSDs from the very beginning was that they offer an integrated user and development experience (as opposed to Linux), much like Windows did. What I did not like was that I had to recompile everything I wanted to use from scratch, which was and still is fairly problematic on low-powered machines. As an example, I spent a lot of time getting NetBSD to run on an old PowerBook G4 and the only way to do this was by fiddling with compile-time settings for the kernel. It’d have been much easier for me (not the developers!) if these settings had been available as runtime boot loader options.
For a really long time now, I’ve been of the opinion that applications should be written as if they were closed-source even if they are actually open-source. The same applies to company-internal applications where you can almost always see the source, and this reminds me of Steve Yegge’s platform rant (can’t find the original now). This is why I spent so much time back in my NetBSD years trying to make the system completely usable and customizable only from binary builds, without having to rebuild anything from scratch (see e.g. sysupgrade or pkg_comp). My goal was to have a compiler-less home server, and I was able to do for a long time.
Binary-only interfaces come at a huge cost though. Windows is famously-known for its ~forever backwards compatibility at the binary level, which is great for software vendors but I’m sure is cringing (or not, as somebody who has actually done this for a living tells me after reading this!) for anyone having to maintain the internal system interfaces.
There is this article that made the rounds just yesterday titled “C Isn’t A Programming Language Anymore” and you should go read at least its “Case Study: MINIDUMP_HANDLE_DATA” section. Or you can also read one of the many posts by Raymond Chen on how Windows has to deal with backwards compatibility.
Enough for today. I’m sorry I didn’t go into details on how exactly Windows is introspectable and debuggable. The reason is, simply, that I don’t know enough yet. I mentioned a couple of books earlier on this topic and, while they are very promising… I have barely had the time to read them. Tomorrow, we have just one more topic to cover before closing the series, and that will be about package management on Windows.