ISSにブレークポイントの機能があるので、それを拡張して、デバッグをしやすくしよう。
レジスタの一覧をダンプする機能と、任意のレジスタの値を取得する機能を追加した。
int Lua_GetReg (lua_State *L) { // Getting Arguments #ifdef ARCH_MIPS MipsEnv *env = static_cast<MipsEnv *>(lua_touserdata (L, 1)); #else // ARCH_MIPS #ifdef ARCH_RISCV RiscvEnv *env = static_cast<RiscvEnv *>(lua_touserdata (L, 1)); #endif // ARCH_RISCV #endif // ARCH_MIPS RegAddr_t reg_addr = lua_tointeger (L, 2); env->DebugPrint ("<get reg: r%02d=%08x>\n", reg_addr, env->GetGReg (reg_addr)); return 0; } int Lua_DumpRegs (lua_State *L) { // Getting Arguments #ifdef ARCH_MIPS MipsEnv *env = static_cast<MipsEnv *>(lua_touserdata (L, 1)); #else // ARCH_MIPS #ifdef ARCH_RISCV RiscvEnv *env = static_cast<RiscvEnv *>(lua_touserdata (L, 1)); #endif // ARCH_RISCV #endif // ARCH_MIPS env->DebugPrint ("<dump regs>\n"); for (int reg_addr = 0; reg_addr < 32; reg_addr++) { env->DebugPrint (" r%02d=%08x\n", reg_addr, env->GetGReg (reg_addr)); } return 0; }
今回は、freerange()とkfree()が呼ばれたときに、レジスタの一覧をダンプするようにしたい。 init.luaを以下のように設定した。
mips = make_core ("mips") set_pcbreak (mips, get_addr (mips, "freerange")) set_pcbreak (mips, get_addr (mips, "kfree")) v = 0 while (v < 5) do run (mips) dump_regs (mips) v = v + 1 end
早速実行してみる。
swimmer_mips --binfile ~/xv6-mips/kernel --debug --out debug.log --debug_func --debug_gvar --init_pc 0x80100000 --max 1000000 --script init.lua
debug.logを見てみよう。
56 : [801041e8] 8fc5001c : lw r05,0x001c(r30) r30=>8050d6b0 (8050d6cc)=>80400000 r05<=80400000
57 : [801041ec] 0c041097 : jal 0x0041097 r31<=801041f4 pc<=801041f0 pc<=8010425c
58 : [801041f0] 00000000 : sll r00,r00,0x00 r00=>00000000
<Break PC: 8010425c>
<dump regs>
r00=00000000
r01=00000000
r02=80513274
r03=8010b6cc
r04=80515cb0
r05=80400000
r06=00000000
r07=00000000
r08=80105084
r09=10000000
r10=00000000
r11=00000000
r12=00000000
r13=00000000
r14=00000000
r15=00000000
r16=00000000
r17=00000000
r18=00000000
r19=00000000
r20=00000000
r21=00000000
r22=00000000
r23=00000000
r24=00000000
r25=00000000
r26=00000000
r27=00000000
r28=00000000
r29=8050d6b0
r30=8050d6b0
r31=801041f4
<Run: MIPS>
<Func: freerange 0x8010425c>
59 : [8010425c] 27bdffe0 : addiu r29,r29,0xffe0 r29=>8050d6b0 r29<=8050d690
60 : [80104260] afbf001c : sw r31,0x001c(r31) r29=>8050d690 r31=>801041f4 (8050d6ac)<=801041f4
61 : [80104264] afbe0018 : sw r30,0x0018(r30) r29=>8050d690 r30=>8050d6b0 (8050d6a8)<=8050d6b0
62 : [80104268] 03a0f021 : addu r30,r29,r00 r29=>8050d690 r00=>00000000 r30<=8050d690
63 : [8010426c] afc40020 : sw r04,0x0020(r04) r30=>8050d690 r04=>80515cb0 (8050d6b0)<=80515cb0
64 : [80104270] afc50024 : sw r05,0x0024(r05) r30=>8050d690 r05=>80400000 (8050d6b4)<=80400000
65 : [80104274] 8fc20020 : lw r02,0x0020(r30) r30=>8050d690 (8050d6b0)=>80515cb0 r02<=80515cb0
66 : [80104278] 24430fff : addiu r03,r02,0x0fff r02=>80515cb0 r03<=80516caf
67 : [8010427c] 2402f000 : addiu r02,r00,0xf000 r00=>00000000 r02<=fffff000
68 : [80104280] 00621024 : and r02,r03,r02 r03=>80516caf r02=>fffff000 r02<=80516000
69 : [80104284] afc20010 : sw r02,0x0010(r02) r30=>8050d690 r02=>80516000 (8050d6a0)<=80516000
70 : [80104288] 080410aa : j 0x00410aa pc<=8010428c pc<=801042a8
71 : [8010428c] 00000000 : sll r00,r00,0x00 r00=>00000000
72 : [801042a8] 8fc20010 : lw r02,0x0010(r30) r30=>8050d690 (8050d6a0)=>80516000 r02<=80516000
73 : [801042ac] 24431000 : addiu r03,r02,0x1000 r02=>80516000 r03<=80517000
kfreeの実行結果を見てみると、
void kfree(char *v) { struct run *r; if((uint)v % PGSIZE || v < end || v2p(v) >= PHYSTOP) panic("kfree");
の v < endが成立していないようだ。これは、メモリマップというか、ブートの方法から考え直さないといけないなあ。
6551 : [80104298] 00000000 : sll r00,r00,0x00 r00=>00000000
<Break PC: 801042d8>
<dump regs>
r00=00000000
r01=00000000
r02=00000000
r03=80401000
r04=80400000
r05=90000000
r06=00000040
r07=00000000
r08=80105084
r09=10000000
r10=00000000
r11=00000000
r12=00000000
r13=00000000
r14=00000000
r15=00000000
r16=00000000
r17=00000000
r18=00000000
r19=00000000
r20=00000000
r21=00000000
r22=00000000
r23=00000000
r24=00000000
r25=00000000
r26=00000000
r27=00000000
r28=00000000
r29=8050d690
r30=8050d690
r31=8010429c
<Run: MIPS>
<Func: kfree 0x801042d8>
6552 : [801042d8] 27bdffe0 : addiu r29,r29,0xffe0 r29=>8050d690 r29<=8050d670
6553 : [801042dc] afbf001c : sw r31,0x001c(r31) r29=>8050d670 r31=>8010429c (8050d68c)<=8010429c
6554 : [801042e0] afbe0018 : sw r30,0x0018(r30) r29=>8050d670 r30=>8050d690 (8050d688)<=8050d690
6555 : [801042e4] 03a0f021 : addu r30,r29,r00 r29=>8050d670 r00=>00000000 r30<=8050d670
6556 : [801042e8] afc40020 : sw r04,0x0020(r04) r30=>8050d670 r04=>80400000 (8050d690)<=80400000
6557 : [801042ec] 8fc20020 : lw r02,0x0020(r30) r30=>8050d670 (8050d690)=>80400000 r02<=80400000
6558 : [801042f0] 30420fff : andi r02,r02,0x0fff r02=>80400000 r02<=00000000
6559 : [801042f4] 1440000f : bne r02,r00,0x000f r02=>00000000 r00=>00000000 pc<=801042f8
6560 : [801042f8] 00000000 : sll r00,r00,0x00 r00=>00000000
6561 : [801042fc] 8fc30020 : lw r03,0x0020(r30) r30=>8050d670 (8050d690)=>80400000 r03<=80400000
6562 : [80104300] 3c028051 : lui r02,0x8051 r02<=80510000
6563 : [80104304] 24425cb0 : addiu r02,r02,0x5cb0 r02=>80510000 r02<=80515cb0
6564 : [80104308] 0062102b : sltu r02,r03,r02 r03=>80400000 r02=>80515cb0 r02<=00000001
6565 : [8010430c] 14400009 : bne r02,r00,0x0009 r02=>00000001 r00=>00000000 pc<=80104310 pc<=80104334
6566 : [80104310] 00000000 : sll r00,r00,0x00 r00=>00000000
6567 : [80104334] 3c028011 : lui r02,0x8011 r02<=80110000
6568 : [80104338] 2444b6d4 : addiu r04,r02,0xb6d4 r02=>80110000 r04<=8010b6d4
6569 : [8010433c] 0c040282 : jal 0x0040282 r31<=80104344 pc<=80104340 pc<=80100a08
6570 : [80104340] 00000000 : sll r00,r00,0x00 r00=>00000000
<Func: panic 0x80100a08>