操作系统真象还原第15章遇到的bug和解决方式(二)

当我在完成带参数的用户程序后,运行出现了bug。在完成加载磁盘上的文件执行时,首先你需要编译源程序,然后根据源程序的大小,将其写到磁盘中,同时需要修改kernel/main.c,因为我们编译后的程序大小和书中给的程序大小不一样

nasm -f elf ./start.S -o ./start.o -g

ar rcs simple_crt.a ../build/string.o ../build/syscall.o \
  ../build/stdio.o ../build/assert.o ./start.o

gcc -Wall -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes \
	-Wsystem-headers -m32 -I ../lib/ -I ../lib/user -I ../fs prog_arg.c -o prog_arg.o

ld prog_arg.o simple_crt.a -o prog_arg -melf_i386

dd if=command/prog_arg of=/home/cccmmf/mycode/os.img bs=512 count=100 seek=300 conv=notrunc

在这里插入图片描述

  uint32_t file_size = 22668; 
  uint32_t sec_cnt = DIV_ROUND_UP(file_size, 512);
  struct disk* sda = &channels[0].devices[0];
  void* prog_buf = sys_malloc(sec_cnt * SECTOR_SIZE);
  ide_read(sda, 300, prog_buf, sec_cnt);
  int32_t fd = sys_open("/prog_arg", O_CREAT|O_RDWR);
  if (fd != -1) {
     if(sys_write(fd, prog_buf, file_size) == -1) {
        printk("file write error!\n");
        while(1);
     }
  }
  sys_close(fd);

当我运行prog_arg后出现了GP异常,如下所示
在这里插入图片描述
在这里插入图片描述
我们接下来使用gdb进行debug,首先我们需要去判断,我们是否执行到了prog_arg(判断GP发生在内核还是prog_arg中),我们是通过shell.c中的myshell函数调用execv,execv最终转变为sys_execv去执行磁盘上的可执行文件,所以我们可以直接在sys_execv上打断点。

当我们执行到下图186行时,我们开始使用s进入intr_exit如下第二个图所示,然后我们继续s,当我们执行到iretd时,开始使用si,单步汇编调试
在这里插入图片描述
在这里插入图片描述

使用si单步调试之后,我们发现我们有一条使用了gs寄存器,按道理来说用户程序肯定是不能操作gs寄存器的,就是该条指令导致了gp异常
在这里插入图片描述
接下来我们使用objdump反汇编prog_arg文件
在这里插入图片描述
在这里插入图片描述
最终发现在main函数里就是有一条指令使用了gs寄存器,接下来我们重新编译prog_arg,重新写入磁盘,使用gcc编译时多加一个参数-fno-stack-protector

nasm -f elf ./start.S -o ./start.o -g

ar rcs simple_crt.a ../build/string.o ../build/syscall.o \
  ../build/stdio.o ../build/assert.o ./start.o

gcc -Wall -c -fno-builtin -W -Wstrict-prototypes -Wmissing-prototypes \
	-Wsystem-headers -m32 -I ../lib/ -I ../lib/user -I ../fs prog_arg.c -o prog_arg.o -fno-stack-protector

ld prog_arg.o simple_crt.a -o prog_arg -melf_i386

dd if=command/prog_arg of=/home/cccmmf/mycode/os.img bs=512 count=100 seek=300 conv=notrunc

然后使用objdump反汇编prog_arg,最终发现使用gs的那条汇编指令没有了
在这里插入图片描述
在这里插入图片描述
接下来重新启动我们的操作系统,将prog_arg读入文件系统,然后运行,最终运行成功在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小林疋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值