「OS」 Gxemul

debug

OS的工具

Posted by Leo on March 28, 2022

进入debug模式

1
gxemul -E testmips -C R3000 -M 64 ./gxemul/vmlinux -V

其中可用的命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
allsettings show all settings
breakpoint ... manipulate breakpoints
continue continue execution
device ... show info about (or manipulate) devices
dump [addr [endaddr]] dump memory contents in hex and ASCII
emuls print a summary of all current emuls
focus x[,y[,z]] changes focus to cpu x, machine x, emul z
help print this help message
itrace toggle instruction_trace on or off
lookup name|addr lookup a symbol by name or address
machine print a summary of the current machine
ninstrs [on|off] toggle (set or unset) show_nr_of_instructions
pause cpuid pause (or unpause) a CPU
print expr evaluate an expression without side-effects
put [b|h|w|d|q] addr, data modify emulated memory contents
quiet [on|off] toggle quiet_mode on or off
quit quit the emulator
reg [cpuid][,c] show GPRs (or coprocessor c's registers)
step [n] single-step one (or n) instruction(s)
tlbdump [cpuid][,r] dump TLB contents (add ',r' for raw data)
trace [on|off] toggle show_trace_tree on or off
unassemble [addr [endaddr]] dump memory contents as instructions
version print version information
x = expr generic assignment

Breakpoint, Step & Unassemble, Dump


GXemul 提供了断点、单步执行(指令级别)的调试功能;除此之外,GXemul 还提供了反汇编、内存 导出等功能。

Add Breakpoint


在控制台输入breakpoint add page_insert, 即可为page_insert设置断点。随后使用 c (continue)命令让模拟器继续运行,模拟器将运行至下一个断点处

step


如下,使用 step 即可让模拟器执行 1 条汇编指令(基本指令)。

1
GXemul> step

进一步地,使用 step 100 即可让模拟器执行 100 条汇编指令(基本指令)。

1
 GXemul> step 100

unassemble


使用 unassemble 命令,导出某一个地址后续(或附近)的汇编指令序列,实践中可以看到感觉像是从头开始汇编

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
GXemul> unassemble
<_start>
80010000: 40806000      mtc0    zr,status
80010004: 00000000      nop
80010008: 40809000      mtc0    zr,watchlo
8001000c: 00000000      nop
80010010: 40809800      mtc0    zr,watchhi
80010014: 00000000      nop
80010018: 40088000      mfc0    t0,config
8001001c: 2401fff8      addiu   at,zr,-8
80010020: 01014024      and     t0,t0,at
80010024: 35080002      ori     t0,t0,0x0002
80010028: 40888000      mtc0    t0,config
8001002c: 0c004010      jal     0x80010040      <main>
80010030: 3c1d8040      lui     sp,0x8040
<loop>
80010034: 0800400d      j       0x80010034      <loop>
80010038: 00000000      nop
8001003c: 00000000      nop
<main>
80010040: 27bdffe8      addiu   sp,sp,-24
80010044: afbf0010      sw      ra,16(sp)
80010048: 3c048001      lui     a0,0x8001
8001004c: 0c00429e      jal     0x80010a78      <printf>

Dump Data

如下,使用 dump 命令,导出某一个地址后续(或附近)的内存信息。下面以查看 curenv 的值以及 其指向的进程控制块为例:

1
2
3
4
5
6
7
8
GXemul> dump curenv
0x800167a0 			804320e8 00000003 00000000 .C .........
0x800167b0 00000002 804321d0 00000000 00000000 .....C!.........
0x800167c0 80432000 00000001 00000000 00000000 .C .............
0x800167d0 00000000 00000000 00000000 00000000 ................
0x800167e0 00000000 00000000 00000000 00000000 ................
..........

前面的是按字存储,16、16的递增

根据 curenv 的定义,其类型为 struct Env * ,因此 0x800167a4 中存储的是一个地址(指向一个 struct Env )。根据上述 dump 结果,可以知道这个全局指针指向了 0x804320e8 这一地址。再通 过 dump 0x804320e8 即可找到当前 curenv 指向的 struct Env

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
GXemul> dump 0x804320e8
0x804320e0 00000000 00000000 ........
0x804320f0 00000001 00000025 00400920 0040d2c4 .......%.@. .@..
0x80432100 0040d2c4 7f3fdfcc 00000000 00000000 .@...?..........
0x80432110 00000000 00000000 00000000 00000000 ................
0x80432120 00000000 00000000 0040d2cc 00000007 .........@......
0x80432130 00000000 7f3fdfcc 00000000 00400920 .....?.......@.
0x80432140 00000000 00000000 00000000 00000000 ................
0x80432150 7f3fdb80 82000000 00000000 7f3fdb80 .?...........?..
0x80432160 00000000 004009d0 10081004 00000000 .....@..........
0x80432170 00000000 00408000 00001000 00400aa0 .....@.......@..
0x80432180 00400aa0 804321d0 800167b4 00000c01 .@...C!...g.....
0x80432190 00000000 00000001 83ff3000 03ff3000 ..........0...0.
0x804321a0 00000000 80019270 00000001 00000000 .......p........
0x804321b0 00000000 00000000 00000000 00000000 ................
0x804321c0 00000000 00000000 00000002 00000000 ................
0x804321d0 00000000 00000000 00000000 00000000 ................
0x804321e0 00000000 00000000 ........

即可查看当前正运行的进程控制块的信息。类似地,可以查看任何全局变量的值,以及大部分内核数 据结构的信息。

dump registers

利用reg命令导出

1
2
3
4
5
6
7
8
9
10
11
GXemul> reg
cpu0:  pc = 80010000    <_start>
cpu0:  hi = 00000000  lo = 00000000
cpu0:                 at = 00000000  v0 = 00000000  v1 = 00000000
cpu0:  a0 = 00000000  a1 = 00000000  a2 = 00000000  a3 = 00000000
cpu0:  t0 = 00000000  t1 = 00000000  t2 = 00000000  t3 = 00000000
cpu0:  t4 = 00000000  t5 = 00000000  t6 = 00000000  t7 = 00000000
cpu0:  s0 = 00000000  s1 = 00000000  s2 = 00000000  s3 = 00000000
cpu0:  s4 = 00000000  s5 = 00000000  s6 = 00000000  s7 = 00000000
cpu0:  t8 = 00000000  t9 = 00000000  k0 = 00000000  k1 = 00000000
cpu0:  gp = 00000000  sp = a0007f00  fp = 00000000  ra = 00000000

还可以reg,0导出CP0的reg

1
2
3
4
5
ul> reg,0
cpu0:    index=00000000   random=00000000 entrylo0=00000000 entrylo1=00000000
cpu0:  context=00000000 pagemask=00001fff    wired=00000000  reserv7=00000000
cpu0: badvaddr=00000000    count=00000000  entryhi=00000000  compare=00000000
cpu0:   status=30000000    cause=00000000      epc=00000000     prid=00000220

利用tlbdump导出TLB的内容

Trace

了解程序的轨迹,利用trace打开开关,用c继续运行。