GSoC Final: radare2 Timeless Debugger
GSoC has almost been finished. I would like to summarize my works: how did I tackle with and what I’ve done. If You are interested in this new feature, I recommend you to read the document radare2 Timeless (Reverse) Debugger
What is Timeless Debugger?
Timeless Debugging is a debugging paradigm, which is very similar to Reverse debugging or Record and Replay. In general, almost all debugger can control program counter of debuggee process forward by similar commands, like run, continue and stepover… Moreover some rich debugger, like gdb, have also ability to seek program counter backward by stepback, continueback commands. This feature is called Reverse debugging and very usefull when you have missed some debuggee’s activities. You can find what is missed by seeking backward and recovering state. However, radare2 had not have this feature before.
Basic concepts
In GSoC term, I’m working on implementation of r2 Timeless(Reverse) Debugger.
The architecture of r2 Timeless Debugger is fundamentally based on traditional debugging concept, Record and Replay (RnR). In RnR, at first you need to run debuggee process and record non-deterministic behavior.
NOTE: Only non deterministic events need to be recorded, because deterministic events can be reproduced by running actual program.
At the beginning
Before GSoC beginning, I’ve added simple record and replay system for radare2.
A new command dts+
can save entire program state, like register and memory dump then,
another new command dsb
can replay until the before address from current pc.
i.e. You can single step back from current pc.
Internally, dsb
command restores program state from the record previously saved by dts+
,
and then, run program from there to desired point.
That’s how program counter can be seeked backward. You can try step backing like:
It works fine, but, program records are implmented as entire memory and register dump. When you record program states at many times, there are many large dumps in memory.
So, during the community bonding period, My works are mainly focused on Reducing size of program records.
Diff-style format for recording
Program records are used to restore before state. So it’s not necessary to hold entire dump.
Only different pages from a previous record are enough for restoring.
So I’ve added new diff style recording format, which saves only changed memory area
from previous recording point.
Architecture overview is as shown in the figure.
(Trace session architecture internal.)
OK. Let’s see this feature.
You can use dts
command to show the all list of program records.
As you can see the result of dts
, session 1 saves only different pages from previous session 0.
Checkpoint
If you run dsb
command just after long loop, you would find that perfomance become very slow. :(
So after GSoC Phase1 began, I’ve implemented simple checkpoint system, that can automatically save trace sessions among long execution. And fixed some bugs related to record and replay functions.
Optional features
After Phase2 began, I’ve added optional feature for recorder. At first I’ve added Import/Export
function of program records. When you take some records and want to export these to filesystem, you can
use dtst <filename>
. Default export path is current directory. It can be changed by e dir.dbgsnap=<path>
. And of course, you can import these records from filesystem like dtsf <filename>
.
After that, I’ve also implmented dts-
and dtsC
commands, delete and add comment for specified record like:
Debug continue back
Program recording and reverse single step function has almost completed. So next, I’ve challeged to add
continue back command, dcb
. Basic usage is same as single step back dsb
, but it can seek program counter backward until hit breakpoint. So it’s reverse version of continue.
Let’s try this feature like:
Reverse debugger for ESIL
According to resume, my works in phase2 has almost finished, but there are plenty of time until finish of phase2. So I’ve developed reverse debugger for ESIL. In ESIL mode, you can record ESIL program state by a new command aets+
and step one back by aesb
command.
Yes. It’s same as dts+
and dsb
in normal debug mode.
You can try these feature under ESIL mode like:
Watchpoint
At Final phase, I was working mainly watchpoint function. It’s efficient feature when use with reverse debugging. For example, when you want to observe some variables changes, you can set watchpoint on it and reverse debug to find where the variable has changed.
You can use dbw <addr> <r/w>
command to set watchpoint at address like:
Moreover, you can set conditional watchpoint like:
Tests
Of course I’ve wrote tests for above new features. Currently these tests are for Linux x86-64 environment. If someone find strange bug under other environments, plz report a issue.
Thanks
Finally, I would like to thanks people:
- radare community
- My mentors, pancake and Álvaro Felipe
- The GSoC organization
GSoC has been finished, but I’d like to continue to develop for r2!
Thank you.