If you have the source code of the program you are debugging you can just use the rsc dwarf- helpers to get a source trace of the program. Here's a sample session:
$ nl hello.c
1 main(int argc, char **argv)
2 {
3 int a = 3;
4 if (a < argc) {
5 printf("Fuck World\n");
6 } else {
7 printf("Hello World\n");
8 }
9 }
$ gcc -g hello.c
$ radare -d ./a.out
[0x465D8810]> !cont sym.main
Continue until (sym.main) = 0x08048374
pre-Breakpoint restored 465d8810
[0x465D8810]>
1 main(int argc, char **argv)
* 2 {
3 int a = 3;
4 if (a < argc) {
5 printf("Fuck World\n");
6 } else {
; 0x08048374 DATA xref from 0x08048307 (entrypoint+0x17)
0x08048374, oeip: lea ecx, [esp+0x4]
0x08048378, eip: and esp, 0xf0
0x0804837b push dword [ecx-0x4]
0x0804837e push ebp
0x0804837f mov ebp, esp
0x08048381 push ecx
; Stack size +20
0x08048382 sub esp, 0x14
; Set var0
0x08048385 mov dword [ebp-0x8], 0x3 ; eax+0x7
; Set var0
0x0804838c, mov eax, [ebp-0x8] ; eax+0x7
; Get var0
0x0804838f cmp eax, [ecx] ; oeax+0xffffff84
0x08048391 jge 0x80483a1 ; 1 = eip+0x29
0x08048393 mov dword [esp], 0x8048480 ; str.Fuck_World
0x0804839a call 0x80482d4 ; 2 = imp_puts
0x0804839f jmp 0x80483ad ; 3 = eip+0x35
0x080483a1 mov dword [esp], 0x804848b ; str.Hello_World
0x080483a8, call 0x80482d4 ; 4 = imp_puts
; Stack size -20
0x080483ad add esp, 0x14
0x080483b0, pop ecx
0x080483b1 pop ebp
0x080483b2 lea esp, [ecx-0x4]
0x080483b5 ret
0x080483b5 ; ------------------------------------
So now we can step until reach the last opcode of sym.main at 0x080483b5:
[0x08048374]> !stepu 0x080483b5
[0x08048374]> at
0x080482d4 - 0x080482da
0x08048374 - 0x08048393
0x080483a1 - 0x080483b2
... (library code ) ...
We can get a one-opcode-trace per line by using the 'at*' command:
[0x080483AD]> at*
0x08048374 1 1
0x08048378 1 2
0x0804837b 1 3
0x0804837e 1 4
0x0804837f 1 5
0x08048381 1 6
0x08048382 1 7
0x08048385 1 8
0x0804838c 1 9
0x0804838f 1 10
0x08048391 1 11
0x080483a1 1 12
0x080483a8 1 13
0x080482d4 1 14
...
We're obviously skipping the library opcodes here, because they do not matter too much now..we have no source code for these libs.
With this output we can feed the 'rsc dwarf-traces' command and get a human-readable output.
[0x080483AD]> at* | rsc dwarf-traces $FILE
2 {
3 int a = 3;
4 if (a < argc) {
7 printf("Hello World\n");
You can modify dwarf-traces to get information about the addr -> file:line from another database and be able to add your own comments here.
You can do the same by using the 'atD' command which is an alias for the previous long command (at*|rsc...).