Hi I'm doing homework about operating system using Pintos. I was asked to find the faulting instruction in one test. The testing framework expected Pintos to output “do-nothing: exit(162)”. This is the standard message that Pintos prints when a process exits. However, Pintos did not output this message; instead, the do-nothing program crashed in userspace due to a memory access violation (a segmentation fault).
#include "tests/lib.h"
int
main (int argc UNUSED, char *argv[] UNUSED)
{
return 162;
}
I looked into the result of this test,
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
The questions :
- What virtual address did the program try to access from userspace that caused it to crash? A: From the result file, I think it's 0xc000008
- What is the virtual address of the instruction that resulted in the crash? A: eip = 0x8048757, it's the virtual address of the instruction.
- To investigate, disassemble the do-nothing binary using objdump. What is the name of the function the program was in when it crashed? Copy the disassembled code for that function onto Gradescope, and identify the instruction at which the program crashed.
I have no idea about how to find the answer of 3. question, the output with "objdump -S do-nothing.o" is really simple :
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
A:
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>
- Find the C code for the function you identified above. For each instruction in the disassembled function in #3, explain in a few words why it’s necessary and/or what it’s trying to do.
#include <syscall.h>
int main (int, char *[]);
void _start (int argc, char *argv[]);
void
_start (int argc, char *argv[])
{
exit (main (argc, argv));
}
- Why did the instruction you identified in #3 try to access memory at the virtual address you identified in #1? Don’t explain this in terms of the values of registers; we’re looking for a higher level explanation. A: I found the faulting instruction but I'm even more confused,
8048757: 8b 44 24 24 mov 0x24(%esp),%eax
**why would this instruction lead to segmentation fault? **
sub $0x1c,%esp
mov 0x24(%esp),%eax
Firstly it allocated some stack space (0x1c), then move the argument argv at 0x24(%esp) [which was 0x8 before stack pointer changed] to %eax, why would this simple instruction lead to segmentation fault?
I am not an expert in PintOS, but I can offer some insight. You are using OBJDUMP on an object file (
.o
). These are unlinked ELF object files without any VMA (Virtual Memory Address) starting point (aka Origin Point) and doesn't include any of the user mode runtime code in each PintOS program. Things like a C startup that sets up the user mode application and starts the code atmain
with theargc
andargv
parameters.What you need to do is build the object file into a user mode program with the normal PintOS build processes. The userland executables have the same name as the
.o
file with the.o
removed.do-nothing
is the name of the executable and it appears these can be found in the directorypintos/src/userprog/build/tests/userprog/
. Run OBJDUMP on this executable, search for address 0x8048757. You should be able to readily find the function name and all the code for it easily. With that information you should be able to answer the 3rd question. The answer you have for question 1 and 2 is correct.