When I was a Virtutech a few years ago we had a product called Hindsight. It looked close to magic when you used it since it allowed you to run code backwards. I assume that the technology is still lurking under the hood in Wind River’s Simics product, now part of Intel. The way the code worked is that as the software executed, Simics would take occasional snapshots of the virtual machine. Then, to run code backwards it would restore a snapshot and rerun forwards all the execution except for the last instruction. You could also track down hard to find bugs, such as random memory overwrites, by setting reverse watchpoints and going back until your data gets clobbered.
I met Greg Law of Undo Software this week. The company is based in Cambridge in the UK. They provide a similar capability for Linux and ARM based systems. They have actually focused on the EDA market as a good proving ground, and all of Cadence, Synopsys and Mentor are using the product internally. They also have a deal with ARM whereby their product is in ARM’s development kits.
The details of how it works are a little different since there is no virtualization going on but the capability is pretty much the same. You can step backwards through the code and watch the changes to variables being undone one at a time. And you can set watchpoints and run backwards in the same way. Making all this work without losing too much performance is hard. The overhead is about a factor of 4 apparently, meaning that the code runs four times slower when using Undo software than when just running natively.
Debugging hasn’t really changed very much since the early days of computers. As Maurice Wilkes said back in the 1950s:”it was on one of my journeys between the EDSAC room and the punching equipment that the realisation came over me with full force that a good part of the remainder of my life was going to be spent finding errors in my own programs.”
Indeed, all of us who have done any programming have spent a good portion of our time finding errors in our own programs. Being able to run code backwards and thus wait for problems to occur before we need to start looking for them makes things a lot more straightforward. When you can only run code forwards then debugging consists of trying to stop the execution just before something bad happens so that it can be looked at in detail. Since you don’t always know what bad thing is going to happen, it is hard to stop in the right place.
As Kernighan and Pike say:“Reason back from the state of the crashed program to determine what could have caused this. Debugging involves backwards reasoning, like solving murder mysteries. Something impossible occurred, and the only solid information is that it really did occur. So we must think backwards from the result to discover the reasons.”
Or, with Undo Software we just run backwards until the problem happens.
Undo Software’s website is here.