The Undo Engine performs a JIT (just-in-time) binary translation of your application’s machine code as it executes, which allows it to capture all sources of non-determinism such as system calls, signals, thread switches and reads from shared memory or device maps.
As your program runs, the Undo Engine stores snapshots of the program address space. These are complete copies of the current state of the program, but since they’re created using the Linux copy-on-write mechanism the impact on your system memory usage is kept to a minimum.
Results of each non-deterministic operation are recorded in an event log stored in the memory of your application process. These non-deterministic operations usually represent a tiny fraction of the instructions executed so the event log is smaller than you might expect. Configure it as a circular buffer, capturing only the most recent history leading up to the bug.
It’s possible to replay an application from any point in time by restoring the program state from a snapshot that was taken prior to that point and running it forwards, re-executing only the deterministic operations. The results of non-deterministic operations are synthesised based on what is stored in the event log.
|Core dumps||Receive a snapshot of the state of the program at the moment that it crashed.||View the entire history of the program’s execution and state. Wind back from the moment that it crashed to see the root cause.|
|Static analysis/profiling tools||Receive reports of potential issues in your code, including theoretical and false positives.||
Record actual failures and solve problems that you are experiencing right now.
|Logging||Receive a coarse history of your program’s execution without a full explanation as to why the program took the course that it did.||
View the entire program’s execution and state (not just what you chose to log). Examine the contents of any variable or memory and see how they change over time.
|Assertions||It’s good programming technique to use assertions liberally in your code but when one fails, it is difficult to locate the root cause.||
Run your code until the assertion fails and then work backwards (and forwards) to zero in on the root cause.
|General purpose debuggers||Gingerly step forwards in an attempt to reach (but not go past) the location of the error and re-run multiple times.||
Run your program once, attack the problem from two directions, and backtrack easily to see exactly what happened and why.
|Other record and replay technologies||Limited support for shared memory or specific CPUs/kernels/VMs. Often unable to attach to a running process or defer recording.||Our technology supports all of these features, and has a team dedicated to product development to help meet your needs.|