Introduction

The debugger is a monumental piece of work and one of the key enabling elements of making Cosmos unique. We have put an immense amount of work into the debugger and will continue to do so even though it takes a lot of time and detracts from resources that could be used to develop Cosmos kernel code. We do this because we believe that every hour put into the debugger will be returned in many times as many hours saved in kernel development. Some users have criticized this approach, but we stand firm in this belief and believe that Cosmos success rests heavily on the debugger and tight Visual Studio integration.

Obstacles

The Visual Studio debugger is only lightly documented (lightly might be a kind adjective). There are few if any samples and much of our progress is the result of sheer determination and experimentation.

---------------

The Debugger

While debugging a normal program might seem easy and obvious, nobody realizes the big works that is under the scenes to make a debugger works.

Debugging an operating system is even harder as often you don’t have necessary instruments to stop execution of the operating system at a point, analyze memory and stack and continue. How would you do that on a pc?

Luckily Cosmos is developed using Visual Studio. Visual Studio has a great debugger interface, which gives you the possibility to write your customized debugger. The interface is known as AD7. There aren’t many info about AD7, but we make the small pieces of docs on MSDN least. In other words AD7 is a bridge between the Visual Studio interface (breakpoints table, watches, stepping etc) and your own debug engine. Now your debug engine might be fake, meaning that it can debug a program that do not exist, if you use AD7 in the right way, and Visual Studio, will show the data as you give, trusting your commands.

Thus, the developers of Cosmos, created a debugger engine which interacts with the operating system and lets us debug it. The debugger of Cosmos is made of 3 pieces: the Debug Stub (DS), the Debug Connector (DC) and the proper Debug Engine (DE).

Debug Stub

The Debug Stub is internal to the kernel, it receives commands from the DE (like “set this breakpoint” or “give me the value of variable x”) and sends back response from its internals.

The Debug Stub however must be written in assembly. Thanks to this approach, if the whole Cosmos goes down or the IL2CPU, you still have the possibility to access the DS to debug. Assembly is forbidden on Cosmos. How do we write then? Using X#, we created a pseudo-language inside C#. It do not contains code to execute, but code to create assembly code. When IL2CPU is executed the files which compose the Debug Stub are not translated as all the Kernel, but they are executed. From their execution, we get an assembly file, which is assembled and integrated in the output of IL2CPU.

Debug Connector

The Debug Connector is the link between DS and DE. There are many flavors of DC. The most used is the Pipe connector. This because, you can configure a virtual machine serial output to a file, and read the same file from Visual Studio. This is called piping. Commands and responses are passed to the Pipe and are transmitted to the OS through the (virtual) serial port. However a (real) Serial Port Connector, an Ethernet Connector, and others are being developed.

Debug Engine

The Debug Engine is run as the project runs inside Visual Studio. It calls the AD7 methods to interact with Visual Studio according to the actions of the DS and the user on Visual Studio.

To complete/rewrite

When a command is sent to DS, DS shall respond when the command is executed with a Complete message followed by the command Id.

TODO: commands from DE to DS and vice-versa

TODO: the AD7 interface