Easy way to debug software state in real time

https://en.wikipedia.org/wiki/Rubber_duck_debugging

By no means the approach I’m showing here is revolutionary. The neat little trick immensely helped me once and I thought maybe it will be helpful for someone in the future. Imagine the following situation:

You are working with a long function in a real time system. The system can have different states at the time. The states depend on the real-time behaviour of the system therefore using conventional debugger and breakpoints are not available to you. You also can’t use strings and don’t have any logging capabilities. Imagine that the only thing available to you is one variable that you can view in real time, plus you have access to all variables that determine particular states. How do you debug the states that are present at every iteration?

Sounds complicated? Hopefully the following snippet will make it slightly more clear:

import random
import time

while True:
    randomInt = random.randint(0,100)
    randomNormalized = random.random()
    caseLessThenHalf = (randomNormalized < 0.5)
    caseEven = ((randomInt % 2) == 0)
    caseMoreThanTen = (randomInt > 10)

    if(caseLessThenHalf):
        #your logic
    elif(caseMoreThanTen):
         #your logic
    else:
         #your logic

    if(caseEven and caseMoreThanTen):
         #your logic
    else:
         #your logic

I tried to make the code simple just to present the idea. Let’s assume that the system allows you to see state_variable after each iteration (save it to file, print it to the console, graph it etc.).

Here is the (possibly) non-revolutionary way to easily show the states in real time:

import random
import time

caseCounter = 0
randomInt = random.randint(0,100)
randomNormalized = random.random()
caseLessThenHalf = (randomNormalized < 0.5)
caseEven = ((randomInt % 2) == 0)
caseMoreThanTen = (randomInt > 10)

if(caseLessThenHalf):
    caseCounter += 1
elif(caseMoreThanTen):
    caseCounter += 2
else:
    caseCounter += 4

if(caseEven and caseMoreThanTen):
    caseCounter += 8
else:
    caseCounter += 16

print (caseCounter)

Interpreting the output

The only thing left is to interpret the output. Let’s say our state variable is 10 (2+8), here is what we know:

  1. RandomNormalized is >= 0.5 and randomInt is more than ten (caseCounter += 2)

  2. Not only is your randomInt more then ten but it’s also even (caseCounter += 10)

You see 17 on the output?

  1. Your randomNormalized is < 0.5 (caseCounter += 1)

  2. randomInt is either not even or less than ten (caseCounter += 16)

Here, have a play.

In my particular case where we used this approach we were able to plot the state_variable on the graph after each iteration, because we were using powers of 2 we immediately knew what was the state of the system. Ultimately it allowed us to quickly solve the problem but I would always recommend refactoring instead of having to painfully debug the code.

How to extend it?

The code I showed you is far away from being neat. If I were to use this approach more than once I would probably do the following (depending on the language/system etc.):

  1. Put all the logic in a separate class

  2. Have resetCounter function that I call at the beginning of loop/function of interest

  3. Have incrementCounter(int, string) function to which you provide number to increment the counter by and string with function name

  4. Have getCounter() and printCounter() functions that provide you with the number stored by the counter or print all the functions that were called

Mateusz Sadowski

Mateusz Sadowski
Mat is a Robotics consultant and the author of Build Mobile Robots with ROS 2 LiveProject series.

Remote Robotics Consulting - A Five-Year Retrospective

In this blog post, I will highlight some of the updates since my last blog and offer some advice that I hope will be useful for anyone looking to get into technical consulting. Continue reading

I Created a Project-based ROS2 Course

Published on July 05, 2022

IMUs and LiDARs - Not Uncommon Pitfalls

Published on February 24, 2022