进入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继续运行。
-
Previous
「OO」the preview of multithreaded -
Next
「Java multithreaded and design pattern 01」Single Threaded Execution pattern