Closed galihuotui closed 1 year ago
暂时无法复现你的问题,能指出一下对应kernel的C代码对应的出错函数吗?
暂时无法复现你的问题,能指出一下对应kernel的C代码对应的出错函数吗? 通过dump kernel 发现: 出错是在 __getreent 这个函数的这个指令 mov 0xc003d040,%eax,对应的nemu中mov_o2a_v处理函数来执行取内存操作,直接去取0xc003d040这个地址的值 发生段错误
通过查看汇编语句,这个函数的一个可疑调用路径: __getreent <-- vsnprintf <-- printk
其中调用printk的路径有以下: 1.printk <-- mm_malloc 2.printk <-- init_page
update: 进一步调试指令的实现,发现在指令实现中,有直接使用paddr_read 等类似的方法,可能这里会导致指令执行过程中地址值错误,进一步跟进验证中
指令实现一般不直接使用paddr_read / write 函数
通过对指令中paddr_read / write 函数的调用修改,问题已解决,感谢老师
问题描述:
pa3-3 测试过程中遇到Segmentation fault
调试日志:
使用gdb调试有以下log:
Program received signal SIGSEGV, Segmentation fault. __memcpy_sse2_unaligned () at ../sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S:667 667 ../sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S: No such file or directory. (gdb) bt
0 __memcpy_sse2_unaligned () at ../sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S:667
1 0x0041b532 in hw_mem_read (len=, paddr=)
2 paddr_read (len=, paddr=) at src/memory/memory.c:35
3 laddr_read (laddr=3221475392, len=4) at src/memory/memory.c:62
4 0x0040612f in operand_read (opr=0x49f880) at src/cpu/decode/operand.c:15
5 0x0040c2cc in instr_execute_2op () at src/cpu/instr/mov.c:5
6 0x0040cafd in mov_o2a_v (eip=204689, opcode=161 '\241') at src/cpu/instr/mov.c:21
7 0x00405612 in exec_inst () at src/cpu/cpu.c:147
8 0x0040568c in exec (n=) at src/cpu/cpu.c:71
9 0x0041defa in cmd_c (args=0x434854 "") at src/monitor/ui.c:319
10 ui_mainloop (autorun=1 '\001') at src/monitor/ui.c:319
11 0x0041b38e in single_run (img_file_path=0x84b2400 "./kernel/kernel.img",
12 0x004043f3 in main (argc=5, argv=0xbffff304) at src/main.c:158
(gdb) p/x 204689 $1 = 0x31f91 (gdb) p/x 3221475392 $2 = 0xc003d040 (gdb)
问题分析:
其中mov_o2a_v 这条指令地址是c0031f91,完整内容如下:
c0031f90 <__getreent>: c0031f90: 55 push %ebp c0031f91: a1 40 d0 03 c0 mov 0xc003d040,%eax c0031f96: 89 e5 mov %esp,%ebp c0031f98: 5d pop %ebp c0031f99: c3 ret
c0031f9a: 66 90 xchg %ax,%ax c0031f9c: 66 90 xchg %ax,%ax c0031f9e: 66 90 xchg %ax,%ax
以上指令传递给 laddr_read 方法的参数是0xc003d040 由于此时kernel还没有设置开启内存分页模式(此时cpu.cr0.pg==0),所以直接继续调用paddr_read 和hw_mem_read ,方法参数依旧是0xc003d040,最终造成了段错误,
这个问题暂时还没有解决,还在持续跟进,不知老师可否有空指点下解决思路