Hacker News new | ask | show | jobs
by mark_undoio 922 days ago
As byefruit says above - we (undo.io) sell a Java Time Travel Debugger.

If anybody wants to try it, they should get in touch with us.

Our Java tech is based on an underlying record/replay engine that works at the level of machine instructions / syscalls to record the entire process. On top of that we've added the necessary cleverness to show what that means at Java level (so normal source-level debugging works).

That's different to e.g. Chronon, which I think was a pure Java solution: https://blog.jetbrains.com/idea/2014/03/try-chronon-debugger... It had some flexibility (e.g. only record certain classes) but at the cost of quite considerable slowdown and very large storage requirements.

2 comments

Ah, did not realize you all at Undo did a Java implementation as well. I knew about Chronon which was probably the most well-known Java solution (as much as that means) during that spate of new time travel debuggers at the time, but when I looked it up again for my comment it appeared to be defunct after being largely unmaintained for years.
This would be heavily tied to the JVM you’re using, no? Do you have to keep updating this as it evolves?
The short answer is yes - but not as tightly as you'd think. We don't need a deep awareness of what the JVM is doing, e.g. its internal data structures are largely opaque to us.

When we need to reconstruct state we always have the option of time travelling the process and re-executing to drill down on the details, though that's only required when you're replaying a recording.

(the result is that it's quite feasible to update to new JVMs and to support multiple at once)
Hmm, so what do you do to answer questions like "what code corresponds to this address" or "what object is this allocation"? Run the recording, ask the JVM itself using its introspection interfaces in your replay by forking it?
At lower optimisation levels there's a register allocated by the JVM to refer back to the bytecode, which makes things easy. In principle they could change that with a JVM revision - but in practice they don't, so it's an easy cheat.

We have some ability to walk data structures and the re-compute the program's behaviour by other means, which I probably shouldn't get into here. I think we could fall back on that more-or-less completely if we couldn't retrieve the bytecode pointer directly.

The fact the JVM introduces Safe Points to help it transition between optimisation levels is quite helpful!

Our original intention was to always fork a copy of the JVM back in time to handle Java debug protocol requests but that turned out to be painful and, thankfully, also unnecessary.