ics-nju-wl / icspa-public

ICSPA for MOOC
51 stars 21 forks source link

PA-3-3遭遇段错误,还在跟进中,希望老师指点下思路 #4

Closed galihuotui closed 1 year ago

galihuotui commented 1 year ago

问题描述:

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=)

at src/memory/memory.c:20

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",

elf_file_path=0x84b2000 <elf_path> "./testcase/bin/mov") at src/main.c:75

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,最终造成了段错误,

这个问题暂时还没有解决,还在持续跟进,不知老师可否有空指点下解决思路

wangliang-cs commented 1 year ago

暂时无法复现你的问题,能指出一下对应kernel的C代码对应的出错函数吗?

galihuotui commented 1 year ago

暂时无法复现你的问题,能指出一下对应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

galihuotui commented 1 year ago

update: 进一步调试指令的实现,发现在指令实现中,有直接使用paddr_read 等类似的方法,可能这里会导致指令执行过程中地址值错误,进一步跟进验证中

ics-nju-wl commented 1 year ago

指令实现一般不直接使用paddr_read / write 函数

galihuotui commented 1 year ago

通过对指令中paddr_read / write 函数的调用修改,问题已解决,感谢老师