GDB can almost be a dynamic computing environment:
$ gdb ./txr
GNU gdb [ ... ]
[ ... ]
Reading symbols from /home/kaz/txr/txr...done.
(gdb) b eval
Breakpoint 1 at 0x808f6b0: file eval.c, line 969.
(gdb) r -p '(+ 2 2)'
Starting program: /home/kaz/txr/txr -p '(+ 2 2)'
Breakpoint 1, eval (form=0xb7fb919c, env=0xb7fb92ac, ctx_form=0xb7fb919c)
at eval.c:969
969 {
(gdb) p d(form)
(+ 2 2)
$1 = void
(gdb) p d(cons(form, form))
((+ 2 2) + 2 2)
$2 = void
(gdb) p d(cdr(form))
(2 2)
$3 = void
(gdb) p d(cons(0x1, 0x1))
(0 . 0)
$4 = void
(gdb) p cons(0x1, 0x0)
$5 = (obj_t *) 0xb7fb921c
(gdb) p cons(0x9, $5)
$6 = (obj_t *) 0xb7fb920c
(gdb) p cons(0x19, $6)
$7 = (obj_t *) 0xb7fb91fc
(gdb) p d($7)
(6 2 0)
You can test functions that are not even called anywhere from the C code. The d function is such a function; it's only there for use out of GDB. (gdb) p (0)
$10 = 0
(gdb) p d(0)
nil
$11 = void
(gdb) p t
$12 = (val) 0xb7fe5eac
(gdb) p d(t)
t
$13 = void
(gdb) p typeof(t)
$14 = (obj_t *) 0xb7fe5d3c
(gdb) p d(typeof(t))
sym
$15 = void
(gdb) p d(symbol_name(t))
"t"
$16 = void
(gdb) p d(symbol_name(0))
"nil"
$17 = void
Take out the trash, and show it: (gdb) p gc()
$18 = void
(gdb) p d($7)
#<garbage: 0xb7fb91fc>