Differences between revisions 1 and 2
Revision 1 as of 2009-10-17 21:02:23
Size: 1455
Editor: AS-40816
Comment:
Revision 2 as of 2009-10-17 21:33:09
Size: 4953
Editor: AS-40816
Comment: First chapter, "quick start", of process record tutorial
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
== Process Record Tutorial == = Process Record Tutorial =
Line 8: Line 8:
<<TableOfContents(4)>>
=== Quick Start ===
<<TableOfContents(3)>>
== Quick Start ==
Line 53: Line 53:

=== run to the end of the program ===
Now let's make a common mistake -- say "continue" without having set any breakpoints.
Your program will run, but process record will detect when it exits, and ask you whether
you want to stop it before exiting. Say yes.

{{{
(gdb) continue
Continuing.
The next instruction is syscall exit_group. It will make the program exit. Do you want to stop the program?([y] or n) yes
Process record: inferior program stopped.

Program received signal SIGTRAP, Trace/breakpoint trap.
0x005037a0 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
(gdb)
}}}

=== reverse-continue ===
You are now at the very last instruction before your program will exit. However, the execution of your program has been recorded, and you can now return to the beginning and replay it.

To return to the beginning, just use the new "reverse-continue" command. This will execute your program in reverse, and since there are still no breakpoints, it will run all the way back to the start of the recording, and then stop.

{{{
(gdb) reverse-continue
Continuing.

No more reverse-execution history.
main ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:34
34 xyz = 0; /* break in main */
(gdb)
}}}

=== forward replay ===
This time, let's set some breakpoints.
{{{
(gdb) break foo
(gdb) break bar
(gdb) continue
Continuing.

Breakpoint 2, foo ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:28
28 xyz = 1; /* break in foo */
(gdb) continue
Continuing.

Breakpoint 3, bar ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:22
22 xyz = 2; /* break in bar */
(gdb) backtrace
#0 bar ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:22
#1 0x08048366 in foo ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:29
#2 0x08048393 in main ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:35
(gdb)
}}}
Looks just like an ordinary debugging session -- but you are now replaying the execution log that was made earlier when your program ran without any breakpoints.

=== backward replay ===

To finish out this quick start, let's play to the end and then run backwards.

{{{
(gdb) continue
Continuing.

No more reverse-execution history.
0x005037a0 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
(gdb) reverse-continue
Continuing.

Breakpoint 3, bar ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:22
22 xyz = 2; /* break in bar */
(gdb) reverse-continue
Continuing.

Breakpoint 2, foo ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:28
28 xyz = 1; /* break in foo */
(gdb) reverse-continue
Continuing.

No more reverse-execution history.
main ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:34
34 xyz = 0; /* break in main */
(gdb)
}}}
You'll notice that in replaying the program backwards, we hit the same breakpoints, but in the opposite order.
That's the key observation for this quick start -- that you can replay the recorded execution log forward and backward,
and that when replaying backward, the same events occur but in the opposite order.

Process Record Tutorial

This is a short tutorial on how to use gdb's Process Record feature.

Process Record lets you:

  • Record a program's execution and play it back.
  • Debug a program in reverse (see Reverse Debugging).

Quick Start

To get started using process record, all you need is gdb version 7.0 or later, and an x86 computer running Linux. And, of course, a program to debug. Here's a simple one:

int xyz;

int bar ()
{
  xyz = 2; /* break in bar */
  return 1;
}

int foo ()
{
  xyz = 1; /* break in foo */
  return bar ();
}

int main ()
{
  xyz = 0;      /* break in main */
  foo ();
  return (xyz == 2 ? 0 : 1);
}               /* end of main */

Compile this program (with -g of course), and load it into gdb, then do the following.

(gdb) break main
(gdb) run
(gdb) record

This will turn on process recording, which will now record all subsequent instructions executed by the program being debugged.

Note that you can start process recording at any point (not just at main). You may choose to start it later, or even earlier. The only restriction is that your program has to be running (so you have to type "run" before "record"). If you want to start recording from the very first instruction of your program, you can do it like this:

(gdb) break _start
(gdb) run
(gdb) record

run to the end of the program

Now let's make a common mistake -- say "continue" without having set any breakpoints. Your program will run, but process record will detect when it exits, and ask you whether you want to stop it before exiting. Say yes.

(gdb) continue
Continuing.
The next instruction is syscall exit_group.  It will make the program exit.  Do you want to stop the program?([y] or n) yes
Process record: inferior program stopped.

Program received signal SIGTRAP, Trace/breakpoint trap.
0x005037a0 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
(gdb)

reverse-continue

You are now at the very last instruction before your program will exit. However, the execution of your program has been recorded, and you can now return to the beginning and replay it.

To return to the beginning, just use the new "reverse-continue" command. This will execute your program in reverse, and since there are still no breakpoints, it will run all the way back to the start of the recording, and then stop.

(gdb) reverse-continue
Continuing.

No more reverse-execution history.
main ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:34
34        xyz = 0;      /* break in main */
(gdb)

forward replay

This time, let's set some breakpoints.

(gdb) break foo
(gdb) break bar
(gdb) continue
Continuing.

Breakpoint 2, foo ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:28
28        xyz = 1; /* break in foo */
(gdb) continue
Continuing.

Breakpoint 3, bar ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:22
22        xyz = 2; /* break in bar */
(gdb) backtrace
#0  bar ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:22
#1  0x08048366 in foo ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:29
#2  0x08048393 in main ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:35
(gdb)

Looks just like an ordinary debugging session -- but you are now replaying the execution log that was made earlier when your program ran without any breakpoints.

backward replay

To finish out this quick start, let's play to the end and then run backwards.

(gdb) continue
Continuing.

No more reverse-execution history.
0x005037a0 in _dl_sysinfo_int80 () from /lib/ld-linux.so.2
(gdb) reverse-continue
Continuing.

Breakpoint 3, bar ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:22
22        xyz = 2; /* break in bar */
(gdb) reverse-continue
Continuing.

Breakpoint 2, foo ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:28
28        xyz = 1; /* break in foo */
(gdb) reverse-continue
Continuing.

No more reverse-execution history.
main ()
    at /data/home/msnyder/cvs/localhost/dumpload/gdb/testsuite/gdb.reverse/break-reverse.c:34
34        xyz = 0;      /* break in main */
(gdb)

You'll notice that in replaying the program backwards, we hit the same breakpoints, but in the opposite order. That's the key observation for this quick start -- that you can replay the recorded execution log forward and backward, and that when replaying backward, the same events occur but in the opposite order.

None: ProcessRecord/Tutorial (last edited 2009-10-17 23:01:13 by AS-40816)

All content (C) 2008 Free Software Foundation. For terms of use, redistribution, and modification, please see the WikiLicense page.