Snapshots as an Undo Mechanism

Often when you move the process forward, you accidentally go too far. For example, you may step over a call that you should have stepped into.

In a program that does not use multiple threads, you can use snapshots to save your state before you step over the call. Then clone that snapshot to position another process just before the call so you can step into it.

The following example shows the stages of a snapshot being used in this way:

  1. The first stage is to build the program and start debugging.

  2. The next stage is to stop the process just before the call and take a snapshot. You can see you are just before the call because the right bracket (>) to the left of the source list shows the line about to be executed.

(idb) next 2

stopped at [int main(void):187 0x1200024b8]

    187     nodeList.append(newNode);

(idb) list $curline - 10:20

    177

    178 //  The driver for this test

    179 //

    180 main()

    181 {

    182     List<Node> nodeList;

    183

    184     // add entries to list

    185     //

    186     IntNode* newNode = new IntNode(1);

>   187     nodeList.append(newNode);

    188

    189     CompoundNode* cNode = new CompoundNode(12.345, 2);

    190     nodeList.append(cNode);

    191

    192     CompoundNode* cNode1 = new CompoundNode(3.1415, 7);

    193     nodeList.append(cNode1);

    194

    195     nodeList.append(new IntNode(3));

    196

(idb) save snapshot

# 1 saved at 08:41:46 (PID: 1012).

    stopped at [int main(void):187 0x1200024b8]

    187     nodeList.append(newNode);

  1. You now step over the call. The execution is now after the call, shown by the right bracket (>) being on the following source line.

(idb) next

stopped at [int main(void):189 0x1200024d0]

    189     CompoundNode* cNode = new CompoundNode(12.345, 2);

(idb) list $curline - 10:20

    179 //

    180 main()

    181 {

    182     List<Node> nodeList;

    183

    184     // add entries to list

    185     //

    186     IntNode* newNode = new IntNode(1);

    187     nodeList.append(newNode);

    188

>   189     CompoundNode* cNode = new CompoundNode(12.345, 2);

    190     nodeList.append(cNode);

    191

    192     CompoundNode* cNode1 = new CompoundNode(3.1415, 7);

    193     nodeList.append(cNode1);

    194

    195     nodeList.append(new IntNode(3));

    196

    197     IntNode* newNode2 = new IntNode(4);

    198     nodeList.append(newNode2);

  1. Oh, how you wish you hadn't done that! No problem, just clone that snapshot you made.

(idb) clone snapshot

Process has exited

Process 1009 cloned from Snapshot 1.

# 1 saved at 08:41:46 (PID: 1012).

    stopped at [int main(void):187 0x1200024b8]

    187     nodeList.append(newNode);

  1. Now you are in a new process before the call is executed.

(idb) list $curline - 10:20

    177

    178 //  The driver for this test

    179 //

    180 main()

    181 {

    182     List<Node> nodeList;

    183

    184     // add entries to list

    185     //

    186     IntNode* newNode = new IntNode(1);

>   187     nodeList.append(newNode);

    188

    189     CompoundNode* cNode = new CompoundNode(12.345, 2);

    190     nodeList.append(cNode);

    191

    192     CompoundNode* cNode1 = new CompoundNode(3.1415, 7);

    193     nodeList.append(cNode1);

    194

    195     nodeList.append(new IntNode(3));

    196

Note:

 fork() was used by the debugger both to create the snapshot and to clone it.