首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用objdump查找导致崩溃的指令

如何使用objdump查找导致崩溃的指令
EN

Stack Overflow用户
提问于 2020-12-02 16:24:44
回答 1查看 1.4K关注 0票数 1

嗨,我正在做关于使用Pintos操作系统的作业。我被要求在一次测试中找到错误说明。测试框架期望Pintos输出“什么都不做:退出(162)”。这是当进程退出时Pintos打印的标准消息。但是,Pintos没有输出此消息;相反,由于内存访问冲突(分段错误),无所事事程序在用户空间崩溃。

代码语言:javascript
运行
复制
#include "tests/lib.h"

int
main (int argc UNUSED, char *argv[] UNUSED)
{
  return 162;
}

我调查了这次测试的结果,

代码语言:javascript
运行
复制
FAIL
Test output failed to match any acceptable form.

Acceptable output:
  do-nothing: exit(162)
Differences in `diff -u' format:
- do-nothing: exit(162)
+ Page fault at 0xc0000008: rights violation error reading page in user context.
+ do-nothing: dying due to interrupt 0x0e (#PF Page-Fault Exception).
+ Interrupt 0x0e (#PF Page-Fault Exception) at eip=0x8048757
+  cr2=c0000008 error=00000005
+  eax=00000000 ebx=00000000 ecx=00000000 edx=00000000
+  esi=00000000 edi=00000000 esp=bfffffe4 ebp=00000000
+  cs=001b ds=0023 es=0023 ss=0023

问题如下:

程序试图从用户空间访问什么虚拟地址,从而导致崩溃? 0xc000008

  • What A:从结果文件中,我认为它是导致崩溃的指令的虚拟地址?A: eip = 0x8048757,它是instruction.

  • To调查的虚拟地址,使用objdump反汇编do-nothing二进制文件。程序崩溃时所在函数的名称是什么?将该函数的解压缩代码复制到Gradescope,并标识程序崩溃的指令.

我不知道如何找到3.问题的答案,带有"objdump -S do-nothing.o.o“的输出非常简单:

代码语言:javascript
运行
复制
Disassembly of section .text:

00000000 <main>:

int
main (int argc UNUSED, char *argv[] UNUSED)
{
  return 162;
}
   0:   b8 a2 00 00 00          mov    $0xa2,%eax
   5:   c3                      ret    

答:

代码语言:javascript
运行
复制
void
_start (int argc, char *argv[])
{
 8048754:   83 ec 1c                sub    $0x1c,%esp
  exit (main (argc, argv));
 8048757:   8b 44 24 24             mov    0x24(%esp),%eax
 804875b:   89 44 24 04             mov    %eax,0x4(%esp)
 804875f:   8b 44 24 20             mov    0x20(%esp),%eax
 8048763:   89 04 24                mov    %eax,(%esp)
 8048766:   e8 35 f9 ff ff          call   80480a0 <main>
 804876b:   89 04 24                mov    %eax,(%esp)
 804876e:   e8 49 1b 00 00          call   804a2bc <exit>

  1. 为您在上面标识的函数找到C代码。对于#3中拆解函数中的每一条指令,请用几句话解释为什么需要它和/或它想做什么。

代码语言:javascript
运行
复制
#include <syscall.h>

int main (int, char *[]);
void _start (int argc, char *argv[]);

void
_start (int argc, char *argv[])
{
  exit (main (argc, argv));
}

  1. 为什么您在#3中标识的指令试图访问您在#1中标识的虚拟地址上的内存?不要用寄存器的值来解释这一点;我们正在寻找更高层次的解释。

,我发现了错误指令,但我更困惑了

代码语言:javascript
运行
复制
8048757:    8b 44 24 24             mov    0x24(%esp),%eax

**为什么这个指令会导致分割错误?**

代码语言:javascript
运行
复制
sub    $0x1c,%esp
mov    0x24(%esp),%eax

首先分配一些堆栈空间(0x1c),然后在0x24(%esp)处移动参数argv,在堆栈指针更改为%eax之前为0x8,为什么这个简单的指令会导致分段错误?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-02 20:22:52

我不是PintOS方面的专家,但我可以提供一些见解。在对象文件(.o)上使用OBJDUMP。这些是未链接的ELF对象文件,没有任何VMA (虚拟内存地址)起始点(又名原产地点),并且在每个PintOS程序中不包含任何用户模式运行时代码。比如C启动,它设置用户模式应用程序,并在main上使用argcargv参数启动代码。

您需要做的是将对象文件构建为具有正常PintOS生成过程的用户模式程序。userland可执行文件的名称与删除了.o文件的.o文件相同。do-nothing是可执行文件的名称,看起来它们可以在pintos/src/userprog/build/tests/userprog/目录中找到。在此可执行文件上运行OBJDUMP,搜索地址0x8048757。您应该能够轻松地找到函数名和它的所有代码。有了这些信息,你就可以回答第三个问题了。你对问题1和2的回答是正确的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65112092

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档