finish
: Continue running until just after function in the selected stack frame returns. Print the returned value (if any). This command can be abbreviated as fin
.
advance <location>: runs code until the instructionpointer gets to the specified location.
(gdb) x/10i $eip
=> 0x80105740 <trap>: push %ebp
0x80105741 <trap+1>: mov %esp,%ebp
0x80105743 <trap+3>: push %edi
0x80105744 <trap+4>: push %esi
0x80105745 <trap+5>: push %ebx
0x80105746 <trap+6>: sub $0x1c,%esp
0x80105749 <trap+9>: mov 0x8(%ebp),%edi
0x8010574c <trap+12>: mov 0x30(%edi),%eax
0x8010574f <trap+15>: cmp $0x40,%eax
0x80105752 <trap+18>: je 0x80105848 <trap+264>
(gdb) adv *0x80105752
=> 0x80105752 <trap+18>: je 0x80105848 <trap+264>
clear function
/clear filename:function
Delete any breakpoints set at entry to the function function.
next: like si which steps into function calls, but steps over function calls.
----
refer: https://pdos.csail.mit.edu/6.828/2018/labguide.html
See the GDB manual for a full guide to GDB commands. Here are some particularly useful commands for 6.828, some of which don't typically come up outside of OS development.
Ctrl-c
Halt the machine and break in to GDB at the current instruction. If QEMU has multiple virtual CPUs, this halts all of them.
c (or continue)
Continue execution until the next breakpoint or Ctrl-c.
si (or stepi)
Execute one machine instruction.
b function or b file:line (or breakpoint)
Set a breakpoint at the given function or line.
b *addr (or breakpoint)
Set a breakpoint at the EIP addr.
delete breakpoint
delete [breakpoints] [ {ID ... | ID-range ...} ]
(idb) delete breakpoints 1-4 6
(gdb) i b
Num Type Disp Enb Address What
1 breakpoint keep y 0x000002fa
breakpoint already hit 1 time
2 breakpoint keep y 0x8dee1000
(gdb) delete br 2
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x000002fa
breakpoint already hit 1 time
(gdb) delete
Delete all breakpoints? (y or n) y
(gdb)
set print pretty
Enable pretty-printing of arrays and structs.
info registers
Print the general purpose registers, eip, eflags, and the segment selectors. For a much more thorough dump of the machine register state, see QEMU's own info registers command.
info reg ebp print ebp value
info frame prints the current stack frame.
list <location> prints the source code of the functionat the specified location
x/Nx addr
Display a hex dump of N words starting at virtual address addr. If N is omitted, it defaults to 1. addr can be any expression.
x/Nx $esp display contents in stack(esp)
x/Ni addr
Display the N assembly instructions starting at addr. Using $eip as addr will display the instructions at the current instruction pointer.
evaluates a C expression and prints the result as its proper type. It is often more useful than x.The output from p *((struct elfhdr *) 0x10000) is much nicer than the output from x/13x 0x10000.
symbol-file file
(Lab 3+) Switch to symbol file file. When GDB attaches to QEMU, it has no notion of the process boundaries within the virtual machine, so we have to tell it which symbols to use. By default, we configure GDB to use the kernel symbol file, obj/kern/kernel. If the machine is running user code, say hello.c, you can switch to the hello symbol file using symbol-file obj/user/hello.
QEMU represents each virtual CPU as a thread in GDB, so you can use all of GDB's thread-related commands to view or manipulate QEMU's virtual CPUs.
thread n
GDB focuses on one thread (i.e., CPU) at a time. This command switches that focus to thread n, numbered from zero.
info threads
List all threads (i.e., CPUs), including their state (active or halted) and what function they're in.
------------------------------------------------
1. debug a program
$ gdb a.out
(gdb) b tst.c:7
Breakpoint 1 at 0x665: file tst.c, line 7.
(gdb) r
Starting program: /home/hfyin/projects/6.828/others/a.out
Breakpoint 1, func3 () at tst.c:7
warning: Source file is more recent than executable.
7 a += 1;
(gdb) c
2. debug core
$ gdb executable core_file
3. other example (print arguments, display in word rather than byte, finish)
// code sample
pushl %esp
call trap
addl $4, %esp
void
trap(struct trapframe *tf)
{...}
// gdb
(gdb) si
=> 0x8010563a <alltraps+16>: call 0x80105700 <trap>
alltraps () at trapasm.S:20
20 call trap
(gdb)
=> 0x80105700 <trap>: push %ebp
trap (tf=0x8dffefb4) at trap.c:38
38 {
(gdb) x/20wx $esp
0x8dffefac: 0x8010563f 0x8dffefb4 0x00000000 0x000011b9
0x8dffefbc: 0x00003f98 0x8dffefd4 0x00000024 0x00000000
0x8dffefcc: 0x00000024 0x00000010 0x00000000 0x00000000
0x8dffefdc: 0x00000023 0x00000023 0x00000040 0x00000000
0x8dffefec: 0x00000d39 0x0000001b 0x00000216 0x00003f4c
(gdb) p tf
$1 = (struct trapframe *) 0x8dffefb4
(gdb) p *tf
$2 = {edi = 0, esi = 4537, ebp = 16280, oesp = 2382360532, ebx = 36, edx = 0, ecx = 36, eax = 16, gs = 0, padding1 = 0, fs = 0,
padding2 = 0, es = 35, padding3 = 0, ds = 35, padding4 = 0, trapno = 64, err = 0, eip = 3385, cs = 27, padding5 = 0,
eflags = 534, esp = 16204, ss = 35, padding6 = 0}
(gdb) x/4i $eip
=> 0x80105700 <trap>: push %ebp
0x80105701 <trap+1>: mov %esp,%ebp
0x80105703 <trap+3>: push %edi
0x80105704 <trap+4>: push %esi
(gdb) finish
.....
(gdb) x/5x $esp
0x8dffefec: 0x00000d39 0x0000001b 0x00000216 0x00003f4c
0x8dffeffc: 0x00000023
(gdb) x/i $eip
=> 0x8010564c <trapret+10>: iret
(gdb) x/c $esp
0x8dffefec: 57 '9'
(gdb) x/5x $esp
0x8dffefec: 0x39 0x0d 0x00 0x00 0x1b
(gdb) x/5wx $esp
0x8dffefec: 0x00000d39 0x0000001b 0x00000216 0x00003f4c
0x8dffeffc: 0x00000023
(gdb) x/x $esp
0x8dffefec: 0x00000d39
(gdb)
4.