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>