/Teaching/Operating Systems/Tutorials/Using and creating debug flags

Using and creating debug flags

This tutorial is intended to show you the correct use of debug statements in SWEB. After a quick usage demonstration we will create a new debug flag ourselves.

Use of debug flags

Apart from using GDB for SWEB debugging a debug instruction can used. It allows you to output any printf()-like character sequence to the emulator console. As you can see from the basic SWEB a plentitude of debug messages is printed. In order to better distinguish between the various messages, debug flags have been introduced. Thereby you can not only hide certain unwanted debug output but you are also able to print related debug messages within a common debug flag (group).

To make use of the debug() function, you first need to include its header file: #include “console/kprintf.h”.

Now, assuming that you want to print a message using the debug flag SYSCALL you would simply write it this way:

uint32 test_value = 42; 
debug(SYSCALL, “Telling you the answer: %d\n”, test_value);

On execution of your debug statement you will see a colorized output in the emulator console: [SYSCALL ]Telling your the answer: 42

Creating a new debug flag

If you want your own debug flag, you will have to edit two files which are handling all available flags.

Basically all flags are handled in the file common/include/console/debug.h. They are organized in groups and can be enabled or disabled by appending a special flag named OUTPUT_ENABLED. Each flag has assigned a hexadecimal value which causes the flag to be printed. The last two bytes (4 hex digits) enumerate the flags within a group, the two higher bytes (except for the highest one) define the flag group (i.e. Minix, Block Device, Console, etc.). Except for the flag group it remains to your personal preference how you would like to group / enumerate the flags.

For demonstration purposes we will add a flag named SEMAPHORE. Therefore open debug.h and add the flag before the #endif statement: const uint32 SEMAPHORE = 0x00080200 | OUTPUT_ENABLED;. As already mentioned the appending of OUTPUT_ENABLED causes a debug flag to be printed because the graphic card is mapped to the address 0x80000000.

After having registered our debug flag in debug.h we still need to add a case-statement to the switch-clause in common/source/console/kprintf.cpp:

void debug (uint32 flag, const char *fmt, …) {
  ...
  switch (flag)
  {
    ...
    case SEMAPHORE:
      kprintfd (COLORDEBUG("[SEMAPHORE  ]", "36"));
      break;
    ...
  }
  ...
}

As you can see above, we have defined the string [SEMAPHORE ] which is printed to the emulator console. Furthermore, the value 36 represents the chosen ANSI color cyan.

In the following you are given an overview about the available color codes (default background and text color according to your shell (probably black and a light grey):

Value Meaning
30 Foreground: black
31 Foreground: red
32 Foreground: green
33 Foreground: yellow
34 Foreground: blue
35 Foreground: magenta
36 Foreground: cyan
37 Foreground: white
39 Foreground: white
40 Background: black
41 Background: red
42 Background: green
43 Background: yellow
44 Background: blue
45 Background: magenta
46 Background: cyan
47 Background: white
49 Background: black

In case you want to disable colorful messages at all, add the following definition to the top of kprintf.cpp: #define NO_COLOR.

In the conclusion we want to encourage you to limit the amount of debug messages to a reasonable size. If you print absolutely everything you are running into risk of overseeing messages that are really useful for your problem diagnosis. Last but not least, way too much debug output causes the emulator to respond slowly to your interactions.