CS452 - Real-Time Programming - Spring 2015

Lecture 15 - Debugging

Pubilc Service Announcements

  1. Due date for kernel 4: 18 June.
  2. Exam schedule is out; 19.30, 5 August is the date the registrar gave us.

Serial I/O

Timing Inconsistencies

CTS timing.

What you expect to occur when sending to the train controller

  1. The train application puts a byte in the hold register.
  2. The stop bit is transmitted.
  3. A train xmit interrupt occurs.
  4. The train application checks CTS.
  5. If CTS is set, you put the next byte in the hold register.

Sometimes an implementation based on this expectation surprises you. In reality what happens when you are sending to the train controller is the following.

  1. The train application puts a byte in the hold register.
  2. The stop bit is transmitted.
  3. Two things happen in parallel and The second parts of the two actions do not occur in a deterministic order. Thus the result of the final action is not deterministic.
  4. If CTS is set, the train application puts the next byte in the hold register.

Primitives for Serial I/O

We are supposed to support

int Get( int port )


int Put( int port, char c )

These are wrappers for sends to one or more serial servers.

Debugging Real-time Programs

The most common set of debugging tools used by experienced programmers is the oldest: printf, grep & stack trace.

Debugging real-time programs, at its base, is just the same as any other debugging, and just the same as empirical science.

  1. Gather data.
  2. Create a model that explains the data
  3. Test the model
  4. If the model is not correct, go to 1.
  5. Remember that the model is ALWAYS provisional: data collected later may invalidate it, no matter how much data has confirmed it.

But real-time programs are harder to debug. Why? There are new types of bugs.

Critical Races

There is no known method for eliminating critical races.

It is, in principle, impossible to test away critical races. Why?

Tools you might use to assist debugging


The memory contents are not wiped by reset. Some of the most difficult errors can be detected only by using the contents of memory after a reset. Produce useful results by inserting

      str   pc, <magic location>
many places in your code. Redboot can tell you the contents of the magic places after the program crashes. Then, with the assistance of a load map, you can find out where you were in which code when the problem occurred.

You can often find out this information by looking at the garbage output that often appears at the bottom of the screen. One set of eight characters is the hex address of the instruction that could not be executed. With a load map and assembly listings you can find the instruction on which the program died.

In RedBoot you can, in principle, trace any of the kernel data structures by examining the kernel's stack, but it's extremely arduous to do so.


What does it do?

How do you get it started?

Breakpoint is a special case of a particular sort of tool that is very common.

Getting information closer to real-time.

Stack Trace

In single-threaded programs this is often the most useful tool.

What is the equivalent of a stack trace in a real-time multi-tasking environment?

Return to: